拷贝构造函数
拷贝构造函数
拷贝构造是特殊的构造类型,也会影响类内是否会创建默认构造函数。
单纯只有拷贝构造也可以创建对象。
静态数据成员无法在类内初始化,只能在类外(main函数内也不行,得在静态全局区),但可以通过相应对象的接口进行赋值。
拷贝构造是一种通过自身类型来构造自身的构造函数,用户可以自定义拷贝构造,系统会默认给出:
1 | class student{ |
这里系统给出了一个默认拷贝构造,把stud1的数据成员一个一个地赋值给stu2;
创建方法:
1 | class student{ |
注意:①函数名与类名一致
②参数必须是本类型的一个引用变量
③因为只是复制,加上const保险一些
调用时机
一、用同类型对象初始化对象时(只是在定义新对象时可以)
1 | student stu1; |
二、类为函数形参类型时
1 | void test(student a){}; |
对象作为形参传入时,实际上传入的是student类型对象的一个副本,自然调用了拷贝构造。
三、类为函数返回值类型时
1 | student test(student a){ |
对象返回时实际上返回的时对象a的一个副本,事实上这里调用了两次拷贝构造,使用返回的是初始传入对象的副本的副本。
注意问题:浅拷贝与深拷贝
浅拷贝:
我们在使用系统默认拷贝函数时,对象内数据成员是一个一个“=”过去的。这种拷贝正常情况不会出现问题,但是一旦涉及指针,就会出现问题。指针与指针相等实际上仍然指向的是同一段内存,原来对象的内容并没有复制过去,甚至在原对象释放之后,新对象中的指针还会变成野指针。
深拷贝:
我们一般使用浅拷贝就够了,一旦涉及指针,那就需要动态申请内存,所以需要自定义拷贝函数,使用深拷贝。
示例:
1 | class student{ |
问题:拷贝构造可以有多个吗?
不能,这个和析构函数是一个道理的,因为拷贝构造函数析构都是系统自动调用的,不能让系统陷入为难的选择之中。,不能重载。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 窥见!