深拷贝:当对象中含有指针域的时候,在进行对象之间初始化(也就是调用拷贝构造函数)或者是=操作的时候(注:浅两者是不同的情况),将指针所包含的内存空间中的内容也进行拷贝
浅拷贝:当对象中含有指针域的时候,在进行对象之间初始化(也就是调用拷贝构造函数)或者是=操作的时候(注:浅两者是不同的情况),单纯将指针的值(也就是所指内存空间的首地址)拷贝,这就导致两个对象的指针域是同一块内存,所以在对象生存周期完毕时,调用析构函数,释放内存的时候出现core down的情况!
原因分析:因为C++提供的默认拷贝构造函数和=操作都是浅拷贝操作,即只是将指针域进行值复制。
解决方法:重写默认拷贝构造函数 和 重载=操作符
#include "iostream" using namespace std; class Name { public: Name (char *_name) { this->size = strlen(_name)+1; this->pName = (char *)malloc(size); strcpy(this->pName, _name); } // 重写类的拷贝构造函数,使之完成深拷贝 Name (Name &_name) { this->size = _name.size; this->pName = (char *)malloc(size+1); strcpy(this->pName, _name.pName); } ~Name () { free(this->pName); this->size = 0; this->pName = NULL; } // 重写=操作符,使之完成深拷贝 void operator= (Name &_name) { if(this->pName!=NULL) { free(this->pName); this->size = 0; } this->pName = (char *)malloc(_name.size+1); this->size = _name.size; } protected: private: char *pName; int size; }; void RunCopy() { //定义obj2并且用obj1初始化 Name obj1("obj1"); Name obj2 = obj1; //默认的拷贝构造函数,提供的只是浅拷贝 Name obj3("obj3....."); obj2 = obj3; //默认的等号操作,提供的只是浅拷贝 } int main() { RunCopy(); return 0; }
需要注意的点:
1. 深拷贝和浅拷贝发生发生在类成员中包含有指针域的时候。
2. =操作符和对象的初始化是两种不同的东西!!
// 定义obj2并且用obj1初始化 Name obj1("obj1"); Name obj2 = obj1; // 进行的是拷贝构造函数 // 把obj3复制给obj2,用等号操作 Name obj3("obj3....."); obj2 = obj3; // 进行的是等号操作
3. 特别注意:在进行等号操作重载的时,先将原来的内存空间释放,(内存泄漏)
/*.......................*/ // 释放对象原来的内存块 // 防止产生内存泄漏 if(this->pName!=NULL) { free(this->pName); this->size = 0; } /*.......................*/
图示: