无法理解的C++ 浅拷贝函数和‘=’运算符重载构造函数有关问题
无法理解的C++ 浅拷贝函数和‘=’运算符重载构造函数问题
自己写了StringTest类做测试,由于涉及内存在堆上的动态分配,会涉及到浅拷贝和深拷贝!浅拷贝会涉及到内存二次释放,造成内存泄露,这也可以理解。
但是我用浅拷贝后再用‘=’运算符重载拷贝会导致整个程序的数据都是错误的,用深拷贝再用‘=’运算符重载拷贝就没有问题呢,单独测试浅拷贝数据也是正常的,只要一添加上‘=’运算符重载拷贝就连默认的构造函数的数据都是错的。
实在无法理解为什么,浅拷贝加运算符重载时数据都不正确,连默认构造函数的数据都不正确???
浅拷贝运行结果
普通构造函数
浅拷贝构造函数
浅拷贝构造函数
重载运算符构造函数
葺葺葺葺葺葺葺葺柗W!ぞ
葺葺葺葺葺葺葺葺柗W!ぞ
葺葺葺葺葺葺葺葺柗W!ぞ
析构函数
请按任意键继续. . .
深拷贝时运行结果
普通构造函数
深拷贝拷贝构造函数
深拷贝拷贝构造函数
重载运算符构造函数
JustTest
JustTest
JustTest
析构函数
析构函数
析构函数
请按任意键继续. . .
程序如下,深拷贝我暂时注释掉了。
------解决方案--------------------
请参考:
Shallow Copy,Deep Copy,Bitwise Copy和Memberwise Copy
C++类中的4个特殊函数 - 缺省构造函数、拷贝构造函数、拷贝赋值操作符和析构函数
------解决方案--------------------
const char *p ="JustTest";
StringTest str1(p);
StringTest str2(str1);
StringTest str3= str2;
到这里,三个对象共享的数据内容还是"JustTest"
str3 = str1;//这句释放共享的内存,并给str3重新分配内存,一般仍然分配到刚被释放的那个内存,但是系统回收内存再分配时,内存内容会被改写,所以输出乱码。
原因就是这几行:
delete []pdata;//必须要首先释放数据 ////内存内容,也是str1数据已经变了
pdata = new char[strlen(other.pdata)+1];
strcpy(pdata,other.pdata);
另外,重复删除指针时,会出异常,所以你那异常输出里没有输出三个析构函数。
自己写了StringTest类做测试,由于涉及内存在堆上的动态分配,会涉及到浅拷贝和深拷贝!浅拷贝会涉及到内存二次释放,造成内存泄露,这也可以理解。
但是我用浅拷贝后再用‘=’运算符重载拷贝会导致整个程序的数据都是错误的,用深拷贝再用‘=’运算符重载拷贝就没有问题呢,单独测试浅拷贝数据也是正常的,只要一添加上‘=’运算符重载拷贝就连默认的构造函数的数据都是错的。
实在无法理解为什么,浅拷贝加运算符重载时数据都不正确,连默认构造函数的数据都不正确???
浅拷贝运行结果
普通构造函数
浅拷贝构造函数
浅拷贝构造函数
重载运算符构造函数
葺葺葺葺葺葺葺葺柗W!ぞ
葺葺葺葺葺葺葺葺柗W!ぞ
葺葺葺葺葺葺葺葺柗W!ぞ
析构函数
请按任意键继续. . .
深拷贝时运行结果
普通构造函数
深拷贝拷贝构造函数
深拷贝拷贝构造函数
重载运算符构造函数
JustTest
JustTest
JustTest
析构函数
析构函数
析构函数
请按任意键继续. . .
程序如下,深拷贝我暂时注释掉了。
- C/C++ code
#include<iostream> using namespace std; class StringTest { public: //普通构造函数 StringTest(const char *str=NULL); //拷贝构造函数 StringTest(const StringTest &other); //析构函数 ~StringTest(); StringTest& operator=(const StringTest &other); //显示函数 void StrShow() { cout<<pdata<<endl; } private: char *pdata; }; StringTest::StringTest(const char *str) { if(str==NULL) { pdata = new char[1]; *pdata= '\0'; } else { pdata = new char[strlen(str)+1]; if(pdata==NULL) return; strcpy(pdata,str); } cout<<"普通构造函数"<<endl; } StringTest::StringTest(const StringTest &other) { pdata = other.pdata; cout<<"浅拷贝构造函数"<<endl; } /*StringTest::StringTest(const StringTest &other) { pdata = new char[strlen(other.pdata)+1]; if(pdata==NULL) return; strcpy(pdata,other.pdata); cout<<"深拷贝拷贝构造函数"<<endl; }*/ StringTest::~StringTest() { if(pdata != NULL) delete []pdata; cout<<"析构函数"<<endl; } StringTest& StringTest::operator=(const StringTest &other) { if(this == &other) return *this;//自己对自己赋值,直接返回 delete []pdata;//必须要首先释放数据 pdata = new char[strlen(other.pdata)+1]; strcpy(pdata,other.pdata); cout<<"重载运算符构造函数"<<endl; return *this; } void main() { const char *p ="JustTest"; StringTest str1(p); StringTest str2(str1); StringTest str3= str2; str3 = str1; str1.StrShow(); str2.StrShow(); str3.StrShow(); }
------解决方案--------------------
请参考:
Shallow Copy,Deep Copy,Bitwise Copy和Memberwise Copy
C++类中的4个特殊函数 - 缺省构造函数、拷贝构造函数、拷贝赋值操作符和析构函数
------解决方案--------------------
const char *p ="JustTest";
StringTest str1(p);
StringTest str2(str1);
StringTest str3= str2;
到这里,三个对象共享的数据内容还是"JustTest"
str3 = str1;//这句释放共享的内存,并给str3重新分配内存,一般仍然分配到刚被释放的那个内存,但是系统回收内存再分配时,内存内容会被改写,所以输出乱码。
原因就是这几行:
delete []pdata;//必须要首先释放数据 ////内存内容,也是str1数据已经变了
pdata = new char[strlen(other.pdata)+1];
strcpy(pdata,other.pdata);
另外,重复删除指针时,会出异常,所以你那异常输出里没有输出三个析构函数。