浅拷贝,当类对象调用编译器默认的拷贝构造函数和赋值运算符重载函数的时候,仅将待复制对象各个数据成员的值对应复制过来。
深拷贝,通过程序员的重写编写拷贝构造函数和赋值运算符重载函数,让对象中动态成员,重新动态分配空间。【即指针重新指向另一个堆】
举例:
浅拷贝的危害【当有指针的时候就体现出来了】:
using namespace std; class A { public: A(int a) { cout << "类型转换构造函数" << endl; b = new int[a]; }public: int a; int* b; }; int main() { A a(10); A b(a);//使用的是默认的拷贝构造函数 cout << "a:" << (a.b) << " b:" << (b.b); getchar(); return 0; }
结果:
发现a和b中的指针对象都指向同一片堆,所以当a和b某个先被析构的时候,另一个的指针对象就指向了空堆,空指针也就来了。
解决:如果有指针对象就自己定义拷贝构造函数和赋值运算符函数
ps:深拷贝不应该是种和浅拷贝对应的概念,而应该是为了解决浅拷贝的弊端而出现的一种解决思路。
实际操作中因为浅拷贝产生的问题:
如上图有一个读取配置文件的类,有个指针属性指向QSetting,然后通过构造函数传递,默认是浅拷贝,如下:
运行到函数第一行后,this的cfg和入参cfg的QSetting指针指向同一个堆,然后入参在函数结束后释放了这个堆,this的QSetting就找不到这个堆了,以至于我的程序一直卡在了使用QSetting的地方。