深拷贝和浅拷贝的理解

下面是浅拷贝的实例:

class String { public: String(const char* str = "") { if (str == nullptr) { assert(false); return ; } _str = new char[strlen(str + 1)]; strcpy(_str, str); } ~String() { assert(_str); delete[] _str; _str = nullptr; }private: char* _str; }; void Test() { String s1("abcd"); String s2(s1); }

由于s2要调用String类拷贝构造来创建,由于上面没有显式定义则使用系统合成的默认拷贝构造函数。因此二者会调用同一个空间,如下图。
深拷贝和浅拷贝的理解
文章图片

在这种情况下,由于String类没有显示定义拷贝构造和赋值运算符重载,此时编译器会自动合成,当s2调用拷贝构造的时候,编译器会调用默认的拷贝构造函数。问题出现了,由于s1,s2公用同一个空间,所以在释放时一个空间被多次释放,从而引起了系统崩溃。
这就是所谓的**浅拷贝。
浅拷贝 也称位拷贝,编译器只是简单的将对象中的值拷贝过来。当多个对象共享一个资源的时候,当一个对象销毁时空间已经被释放,但是另几个对象不知道资源已经释放了,一位还有效,所以当其他对象继续释放的时候,会出现访问违规的现象。
深拷贝 如果一个类中设计资源的管理,即一个对象被多次使用,拷贝构造和赋值运算符必须显示定义。
class String { public: String(const char* str = "") { if (str == nullptr) { assert(false); return ; } _str = new char[strlen(str + 1)]; strcpy(_str, str); } String(const String& s) :_str(new char[strlen(s._str + 1)]) { strcpy(s._str, _str); } String& operator=(const String& s) { if (this != &s) { char* Pstr = new char[strlen(s._str + 1)]; strcpy(Pstr, s._str); delete[] _str; _str = Pstr; }return *this; } ~String() { assert(_str); delete[] _str; _str = nullptr; }private: char* _str; }; void Test() { String s1("abcd"); String s2(s1); }

【深拷贝和浅拷贝的理解】深拷贝就是给每个对象独立分配资源,保证对象之间不会因共享资源造成多次释放导致程序崩溃。如下图
深拷贝和浅拷贝的理解
文章图片

    推荐阅读