阐述:浅拷贝 及 深拷贝的传统写法
发布时间:2021-12-10 17:32:04 所属栏目:PHP教程 来源:互联网
导读:浅拷贝会造成指针悬挂的问题。 举个例子:两个对象是s1和s2的指针_str都指向new开辟的同一块空间,如下图,主程序结束时,对象逐个撤销,先撤销对象s2,会调用析构函数释放动态分配的内存;再撤销对象s1时,s1._str所指向的内存空间已经是无法访问了,而s2._st
浅拷贝会造成指针悬挂的问题。 举个例子:两个对象是s1和s2的指针_str都指向new开辟的同一块空间,如下图,主程序结束时,对象逐个撤销,先撤销对象s2,会调用析构函数释放动态分配的内存;再撤销对象s1时,s1._str所指向的内存空间已经是无法访问了,而s2._str原先指向的那块内存却无法释放,出现了所谓的指针悬挂! 两个对象企图释放同一块内存,从而导致一块内存被释放两次这也是不行的,运行会出错。 #include <iostream> using namespace std; class String { public: String(char *str) :_str(new char [strlen(str )+1]) { strcpy(_str, str); } String(const String & s) { _str = s._str; } String& operator=(const String & s ) { if (this !=&s) { _str = s._str; } return *this ; } ~String() { delete[] _str; } private: char* _str; }; void Test() { String s1("Lynn" ); String s2=s1; } int main() { Test(); system("pause" ); return 0; } 深拷贝 深拷贝解决了指针悬挂的问题,当调用拷贝构造或赋值运算符的重载函数时,程序会生成一份该内存的拷贝,这样每个指针都会指向一块相对独立的空间,撤销对象时调用析构函数,分别释放他们自己的动态分配的内存,相互之间不影响。如下图: 深拷贝 /////////////////////////////////////////////////////////////////////////////////////// // 写String类的构造函数时一定要注意参数问题 // 首先要考虑到构造的对象分有参数和无参数两种情况 // 构造对象的时候不能直接赋值,否则一块内存两次释放的话程序会出错 // 无参的构造函数不能将_str指针赋值为NULL,因为不能strlen(NULL) // 赋值运算符的重载要考虑到有可能分配内存失败的问题 // 当然,记得要给''分配空间哦 // By:Lynn-Zhang //////////////////////////*****************//////////////////////////////////////////// #include<iostream> using namespace std; class String { public: String(char * str="") //不能strlen(NULL) :_str(new char [strlen(str ) + 1]) { strcpy(_str, str); } String(const String &s) :_str(new char [strlen(s ._str) + 1]) { strcpy(_str, s._str); } //赋值运算符的重载 String& operator=(const String& s) { if (this != &s ) { /* //有可能开辟空间失败,但是却破坏了_str的内容 delete[] _str; _str = new char[strlen(s._str) + 1]; strcpy(_str, s._str); */ char* tmp = new char [strlen(s ._str) + 1]; strcpy(tmp, s._str); delete[] _str; swap(_str, tmp); } return *this ; } char* CStr() { return _str; } ~String() { delete[] _str; } private: char* _str; }; //函数测试 void Test() { String s1("aaaaa" ); cout << s1.CStr() << endl; String s2(s1); cout << s2.CStr() << endl; String s3 = s1; s3= s2; cout << s3.CStr() << endl; String s4; // s4 = s1; cout << s4.CStr() << endl; } int main() { Test(); system("pause" ); return 0; } ![]() (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |