深复制又叫深拷贝;浅复制又叫浅拷贝、位拷贝。为了理解什么叫深复制和浅复制,我们举一个例子,假如我们有一个类叫CDemo,有两个成员,a 和 str.
class CDemo
{
public:
int a;
char *str;
};
我们再定义一个构造函数
CDemo(int pa,char *cstr)
{
this->a = pa;
this->str = new char[104];
strcpy(this->str,cstr);
}
然后执行
CDemo A(10,"hello");
CDemo B = A;
cout <<"A: "<< A.a <<", "<<A.str <<endl;
cout <<"B: "<< B.a <<", "<<B.str <<endl;
执行结果我们可以看到,完成了复制。
然后我们再执行以下代码,将B对象的a置为8,str的第一个字符置为‘K’,然后我们打印对象A和对象B。
B.a = 8;
B.str[0] = 'K';
输出的结果:
我们看到一个问题,修改以后,A对象的字符串也被修改了,这是为什么呢?
这是由于,当我们没有定义复制构造函数时,C++会帮我们生成一个复制构造函数,叫做合成构造函数。但是合成构造函数仅仅只能实现浅拷贝
浅拷贝
我们可以看到只是实现了指针的复制,两个指针实际上指向了同一块内存。浅拷贝存在的问题是,当两个对象其中有一个执行了析构函数,释放了内存,那么另外一个就成了悬垂指针,也就是野指针。
深拷贝
而我们要实现的是深拷贝。
所以我们要定义自己的复制构造函数,来实现复制。
CDemo(CDemo& obj)
{
this->a = obj.a;
//this->str = obj.str;//浅复制,这里只是复制了指针,相当于两个指针指向了同一块内存
this->str = new char[1024];//深复制,开辟新的内存
if (str!=0)
strcpy(this->str,obj.str);
}
同时遵循三法则,定义析构函数,释放内存
CDemo::~CDemo()
{
delete str;
}
这个时候再执行,就会发现A对象的str并没有被修改。