浅拷贝:拷贝对象的指针成员变量和原对象的指针成员变量指向同一块内存空间,当使用delete释放掉一个对象的内存空间后,另一个对象的指针将成为迷途指针,指无所指。如下图:
代码:
class A //浅拷贝
{
public:
A(){x=new int;*x=6;}
~A(){delete x;x=NULL;cout<<"析构函数被调用!"<<endl;}
A(const A&a) //由于复制构造函数一般不变,a只是一个别名,故可以加一个const
{
cout<<"复制构造函数被调用!"<<endl;
x=a.x;
}
void print()const{cout<<*x<<endl;}
void set(int i){*x=i;}
private:
int *x;
};
A *a=new A();
cout<<"a:"<<endl;
a->print();
A b=(*a);//初始化b,并将a指针指向的堆中对象复制给b,此时调用复制构造函数
cout<<"b:"<<endl;
b.print();
//delete a;//报错,因为浅拷贝a,b对象的成员变量指针指向同一块内存空间,删除a指向的内存空间
//则,b对象的指针变成了迷途指针
a=NULL;
深拷贝:拷贝对象的指针成员变量和原对象的指针成员变量分别指向两块不同的内存空间,当任何一个指针变量指向的值改变,或者delete释放内存空间后,另一个对象的指针将不受影响。如下图所示:
代码:
class B //深拷贝
{
public:
B(){x=new int;*x=3;}
~B()
{
delete x;
x=NULL;//由于NULL的值为0,故也等价于x=0;
}
B(B&b) //深层拷贝
{
x=new int;//在堆中开辟空间,
//用复制构造函数创建的新对象的指针成员x来指向它
*x=*(b.x);
}
void set(int i)const{*x=i;}
void print(){cout<<*x<<endl;
private:
int *x;
};
B *b=new B();
cout<<"b:"<<endl;
b->print();
B c=(*b);
c.print();
c.set(666);
cout<<"b:"<<endl;
b->print();
delete b;//不报错!!