在默认的拷贝构造函数中 拷贝的策略是逐个成员一次拷贝 但是一个类可能会拥有资源,当其构造函数分配了一个资源例如堆内存的时候? 会发生什么呢? 如果拷贝构造函数简单的制作了一个该对象的拷贝,而不对它本身进行资源分配和赋值的时候就需要面临一个麻烦的局面: 两个对象都拥有同一个资源。当对象析构的时候,该资源将经历两次资源返还.
例如
#include<iostream>
#include<cstring>
using namespace std;
class Person{
char * name;
public :
Person(char *pn){
name =new char[strlen(pn)+1];
if(name!=0){
strcpy(name,pn);
}
}
~Person(){
cout<<"析构函数调用"<<endl;
delete []name;
}
}
void main(){
{
Person p1("zhangsan");
Person p2(p1); // 调用默认的拷贝构造函数
}
system("pause");
}
不出所料 程序崩溃。这是因为析构p2的时候 将堆中的字符串清空称为空串 然后将堆空间返还给系统。 析构p的时候 因为这时的name是空串所以只输出析构函数调用。当执行delete [] name的时候 系统报错 显示乱码. 这就是浅拷贝. 因为默认的构造函数并没有把资源也复制一份给p2。所以当一个对象创建的时候 并且有指针资源. 这时就需要自己定义拷贝构造函数. 使之不但拷贝成员 也分配和拷贝资源. 在上面的代码中我们只需要定义一个拷贝构造函数即可解决问题. 如下图所示:
Person(Person &p){
cout << "拷贝函数被调用" << endl;
this->name = new char[strlen(p.name) + 1];
if (this->name != 0){
strcpy(this->name, p.name);
}
}