什么时候需要定义自己的拷贝构造函数:
当类中包含有,动态分配成员 或者 指针 的时候。 如果使用默认构造函数,则新构造出来的 新类 和 旧类 里面的指针成员 指向同一个空间, 而当其中一个类 清空掉那个空间 。另一个类的指针就会变成野指针(因为空间已经被清空) , 也就是说默认构造函数是复制值(地址也是值) ps.基本数据类型的数组可以直接使用默认复制构造函数。也就是说有涉及到 自行开辟额外空间 的数据类型 和 指针 的类就需要
什么时候调用拷贝构造函数:
1.一个对象以 值传递 的方式 传入 一个函数
ps: 拷贝构造函数 的形参 必须是 引用, 因为 当对象形参以 值传递 形式 传入 函数时, 会创建一个临时变量 复制对象形参,这个时候又是一样的步骤。创建临时变量。最终堆栈溢出 。 而当传入的是 对象引用 时,函数可以直接使用对象,无需创建新对象。不会造成递归堆栈溢出。(const 可以没有。但最好有。限定只读,并且 const变量不能随意转化为非const,如果传入的是const变量,而形参类型非const,则转化错误)
2.一个对象以 值传递 的方式 从函数 返回
3.一个对象给 另一个对象 初始化的时候
ps: test 是类名, q是已经初始化过的 对象
test k(q) 和 test k = q 调用的拷贝构造函数。因为k是一个未定义的对象
当k定义过了。 调用的则是 = 号操作符
test k; //先定义了(默认构造函数初始化基本类型成员)
k = q; //调用 = 操作符
浅拷贝: 只是简单的值复制。数组也同样有效
深拷贝: 为指针所指向的。 另外开辟新的内存空间并复制 。 拷贝和被拷贝的对象。成员指针指向 包含同一值的。不同内存空间
拷贝构造函数:
声明: test( const test & cpy)
类外定义: test:: test(const test &cpy)
赋值操作符重载
声明:test& test::operate = (const test & cpy)
类外定义: test& test:: operate = (const test & cpy)
两者区别 : 根据是否生成新对象 。 如果是生成对象,则调用复制构造函数 。 如果对象已经有了。则调用 赋值函数
因此两者所定义的内容也应该有所区别。 复制构造函数针对一个 空的对象。 含有指向内存空间的东西都应该另外开辟新空间
赋值函数针对一个 已经存在的对象, 要将原来的成员重新赋值(如果有旧的),并且删除旧的(检查是否是自赋值,释放原有空间,分配新的内存资源,并复制,。返回本对象的引用)