深拷贝&浅拷贝

来源:互联网 发布:双色球七加一中奖算法 编辑:程序博客网 时间:2024/06/05 09:38

class String{public:String(const char* _pStr = "")//构造函数:m_iSize(strlen(_pStr)+1){m_pStr = new char[m_iSize];strcpy(m_pStr, _pStr);m_pStr[m_iSize] = '\0';}String(const String& _string)//拷贝构造函数:m_iSize(_string.m_iSize){if (this != &_string){m_pStr = _string.m_pStr;}}~String()//析构函数{if (NULL != m_pStr){delete[] m_pStr;m_pStr = NULL;}}private:char* m_pStr;int m_iSize;};
测试函数

void FunTest(){String str1("hello");String str2(str1);}
这个程序会出现问题,导致程序奔溃

代码分析:

1.String str1("hello");

调用的是String类的构造函数。首先,给m_pStr分配空间,然后,将形参的内容拷贝到m_pStr中。

2.String str2(str1);

调用的是String类的拷贝构造函数。首先,根据形参m_iSize初始化m_iSize,然后,让m_pStr指向形参m_pStr空间。

3.函数执行过程中,局部变量str2被析构,调用析构函数,将str2.m_pStr所在的空间释放掉。

4.str1被析构,调用析构函数,str1.m_pStr一直指向申请空间,去释放已经str2.m_pStr释放的空间,相同的空间被释放了两次,因此程序奔溃。


浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块空间,当一个对象将这块空间释放之后,另一些对象不知道这块空间已经还给了系统,以为有效,所以在对这块空间进行操作时,发生了访问违规。那么,深拷贝就能解决浅拷贝不能解决的问题,构造对象时拷贝一块跟当前对象一样的大数据块,析构时各自释放各自的数据块。

class String{public:String(const char *pStr = "")//构造函数{if (NULL == pStr){_pStr = new char[1];*_pStr = '\0';}else{_pStr = new char[strlen(pStr) + 1];strcpy(_pStr, pStr);}}~String()//析构函数{if (NULL != _pStr){delete[] _pStr;_pStr = NULL;}}/*//深拷贝  //普通版String(const String &s) //拷贝构造:_pStr(new char[strlen(s._pStr) + 1]){strcpy(_pStr, s._pStr);}String& operator=(const String& s)//赋值运算符重载{if (this != &s){char* tmp = new char[strlen(s._pStr) + 1];//开辟新空间strcpy(tmp, s._pStr);//拷贝delete[] _pStr;//释放旧空间strcpy(_pStr, tmp);}return *this;}*/ //简洁版String(const String &s)//拷贝构造:_pStr(NULL)//解决_pStr为野指针的情况{String tmp(_pStr);swap(_pStr, tmp._pStr);//交换}String& operator=(const String& s)//赋值运算符重载{if (this != &s){String tmp(_pStr);swap(_pStr, tmp._pStr);//交换}return *this;}private:char* _pStr;};void FunTest(){String str1("hello");String str2(str1);}

原创粉丝点击