深拷贝和浅拷贝的概念,使我们在学习类的拷贝构造函数的时候所涉及到的!虽然平常很少涉及,但是我觉得还是有必要拿出来说说:
首先举个例子啊!
class C
{
...
};
class A
{
public:
...
A(const A& rhs)
{
...
this.pc= rhs.pc;
}
private:
...
C* pc;
}
一些与这个问题无关的东西我就不写了,上面这个例子是典型的浅拷贝,不知大家发没发现它存在一个很重大的隐患,就是关于数据成员pc所对应对内存的所属权问题!
当你在某个过程中用到这个拷贝构造函数的时候,把pc所对应的内存堆得地址拷贝了一份!
这样子一份堆内存就被两个不懂对象的成员指针指向,这样子,这样就会产生内存所属权的的混乱,当你通过其中一个对象的析构函数释放掉这份对内存的!那么另一个对象的成员指针指向的地方怎么办,当它也调用析构函数,那不就把一块内存释放了两遍吗?
显然这样做是不合理的!
这就引出了下面的深拷贝!
我们把上面的例子改写一下:
class C
{
...
};
class A
{
public:
...
A(const A& rhs)
{
...
pc=new C();
}
private:
...
C* pc;
}
大家看到了和上面的不同了吧,拷贝的时候我们备用简单的按位拷贝,而是用new新生成了一个C对象并返回指针来初始化pc!这样复制前后的两个对象所指向的堆内存是不一样的!你可以在一个对象里对堆内存为所欲为,而不必担心影响别的对象!因为他们两个本来就没有什么联系了!
这就是深拷贝和浅拷贝的联系和区别!
引用一位仁兄的话来总结一下:如果一个类拥有资源(堆,或者是其它系统资源),当这个类的对象发生复制过程的时候,这些相应的资源也会跟着复制,这个过程就可以叫做深拷贝,反之对象存在资源但复制过程并未复制资源的情况视为浅拷贝。
大家如果平时写含有存在对象指针作为数据成员的类时,没有特殊情况下,就一定要写成深拷贝!以免发生不必要的事情!
小月辛勤发帖,只为与人交流,不要光看不回,不要光看不想,不要光看不批!想看到大家的作品,老自己一个人写会没动力的!