首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

无法理解的C++ 浅拷贝函数和‘=’运算符重载构造函数有关问题

2012-08-02 
无法理解的C++ 浅拷贝函数和‘’运算符重载构造函数问题自己写了StringTest类做测试,由于涉及内存在堆上的

无法理解的C++ 浅拷贝函数和‘=’运算符重载构造函数问题
自己写了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);
另外,重复删除指针时,会出异常,所以你那异常输出里没有输出三个析构函数。

热点排行