C++——深拷贝和浅拷贝
时间:2023-10-24 19:37:02
1.浅拷贝与深拷贝的区别
浅拷贝(默认拷贝函数):直接将原对象或原数组的引用给新对象,新数组、新对象/新数组只是原对象的引用。
深度复制:创建新的对象和数组,复制原对象属性的值(数组的所有元素),是值而不是引用
将数据存储在堆内存中,从而解决指针悬挂问题。当数据成员中有指针时,必须要用深拷贝
(1)如果复制对象中的元素只值,不引用,则深复制与浅复制相同。
复制原对象,产生新对象,修改新对象中的值不会影响原对象,新对象与原对象完全分离。
(2)如果复制对象中的元素包含参考(比如另一个列表存储在一个列表中,另一个列表的参考存储),浅复制和深复制是不同的。
虽然浅拷贝复制了一个原始对象,但它仍然保存在参考中,因此修改新对象中的参考值仍然会改变原对象中列表的值,而新对象并没有完全与原对象分开。
不同的是,它还将创建一个新的引用原对象,即创建一个新列表,然后将新列表引用,以便将新对象与原对象完全分开。
2.为什么要用深拷贝
原数组(对象)在改变新数组(对象)时不会改变
3.有指针时,必须用深拷贝
当数据成员中含有指针时,必须使用深度副本
当使用浅拷贝时,新对象的指针和原对象的指针指向堆叠的相同内存。当新对象和原对象分析时,新对象首先释放动态分配的内存,然后在原对象分析时再次释放已释放的内存。未定义两次以上释放相同动态内存的结果,所有内存泄漏或程序崩溃。
因此,需要深度复制来解决这个问题。当复制对象引用其他资源(如堆、文件、系统等)时(引用可以是指针或引用),对象打开新的资源,而不是简单地赋予复制对象中其他资源引用的指针或引用。
4.结构深拷贝
class MyString { private: char *str; public: MyString(const char *p=nullstr)//缺乏构造函数 :str(nullptr) { if(p!=nullptr) { int len=strlen(p) 1; str=new char[len]; strcpy_s(str,lrn,p); } } MyString(const MyString& ms)///复制构造函数,深复制 { int n = strlen(ms.str) 1; *str = new char[n]; strcpy_s = (str, n, ms.str); //int *str // this->str=new int(*ms.str) } ~MyString()//分析函数 { } };