拷贝构造
拷贝构造就是一种特殊版本的构造函数,
-
格式:
类名(const 类名& that) { //执行给每个成员变量进行赋值 }
-
什么时候会调用拷贝构造:
当使用旧对象(已new的)给新对象(新new的)初始化时,会自动调用拷贝构造
Test t1; //调用无参构造
Test t2=t1; //调用拷贝构造
Test t3(t2); //调用拷贝构造
- 拷贝构造的任务:
负责把旧对象中的成员变量拷贝给新对象,并且编译器默认已经自动生成具有该功能的拷贝构造函数
- 什么时候要显示地写拷贝构造函数?(深拷贝)
普通情况下,编译器自动生成的拷贝构造函数完全够用,但当类中有成员是指针类型,且为该指针成员分配了堆内存,使用默认自动生成的拷贝构造只会对指针的值进行拷贝,此时会导致两个对象的 指针成员指向同一块内存,所以在执行析构函数时会造成重复释放错误,此时应该显示地实现拷贝构造
- 浅拷贝和深拷贝:
浅拷贝:当类中成员有指针且分配了堆内存,只拷贝指针变量的值(直接赋值=)
深拷贝:不拷贝指针变量的值,而是拷贝指针变量所指向的内存的内容(strcpy)
赋值函数(拷贝赋值、赋值运算符函数)
任务:用一个旧对象给另一个旧对象赋值(两个对象都已经完全创建)
Test t1,t2; //无参构造
t1 = t2; //调用赋值操作函数 //t1=t2=t3; t3赋值给t2,返回值为t2,再将t2赋值给t1
类名& operator=(const 类名& that);
{
}
!: 在C++中会把运算符当作函数处理,使用运算符时会调用运算符函数
- 什么时候要显示地写赋值操作函数?
普通情况一般不需要显式地写赋值操作
类似于写显式拷贝构造,当需要进行深拷贝时,就需要显式地写拷贝构造和赋值操作
- 实现赋值操作函数需要注意的问题:
虽然赋值操作雨与拷贝构造的任务相同,都需要深拷贝,但是坏境不同(旧对象、新对象)
1、问题1:被赋值的对象的指针已经分配有内存
①、先释放被赋值的指针指向的原内存
②、根据赋值者的赋值重新申请新内存
③、把赋值者内存的内容深拷贝到新内存中
2、问题2:可能会出现对象自己给自己赋值的情况
通过判断this指针与赋值者的地址是否相同,如果相同,立即返回this结束,如果不同,才进行赋值操作
标签:内存,t2,构造,C++,拷贝,赋值,指针 From: https://www.cnblogs.com/ljf-0804/p/17655090.html