C++中的深拷贝和浅拷贝

时间:2022-05-08 19:50:54

    当类中没有定义拷贝构造函数时候,编译器会产生一个默认构造函数,默认构造函数的作用是把一个对象的全部数据成员赋值给另一个对象的数据成员。C++把对象数据成员的简单赋值称为浅拷贝。浅拷贝的对象和原来对象指向同一个内存空间,如果原来对象析构释放掉空间,拷贝的对象析构时候会出问题。而深拷贝就是自己定义拷贝构造函数,实现数据的真正分配空间与初始化。

    当类的数据成员都是内置类型时候,浅拷贝是没有问题的,但是当类中有动态分配的堆内存空间时候,如果没有定义拷贝构造函数,则类会调用默认构造函数,这样会有两个对象指向同一个堆内存空间,已经开辟的一端堆地址原来是属于对象a的,由于复制过程发生,b对象取得是a已经开辟的堆地址,一旦程序产生析构,释放堆的时候,计算机是不可能清楚这段地址是真正属于谁的,当连续发生两次析构的时候就出现了运行错误。 ,


简单理解:

如果一个对象拥有资源,当这个类对象发生复制时候,如果会分配新的空间就是深拷贝,如果没有分配新的资源就是浅拷贝。如果一个类拥有资源(堆,或者是其它系统资源),当这个类的对象发生复制过程的时候,这个过程就可以叫做深拷贝,反之对象存在资源但复制过程并未复制资源的情况视为浅拷贝。 浅拷贝资源后在释放资源的时候会产生资源归属不清的情况导致程序运行出错,这点尤其需要注意! 

C++浅拷贝就是成员数据之间的一一赋值:把值赋给一一赋给要拷贝的值。但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件。。当值拷贝的时候,两个对象就有用共同的资源,同时对资源可以访问,这样就会出问题。深拷贝就是用来解决这样的问题的,它把资源也赋值一次,使对象拥有不同的资源,但资源的内容是一样的。对于堆资源来说,就是在开辟一片堆内存,把原来的内容拷贝。

如果你拷贝的对象中引用了某个外部的内容(比如分配在堆上的数据),那么在拷贝这个对象的时候,让新旧两个对象指向同一个外部的内容,就是C++浅拷贝;如果在拷贝这个对象的时候为新对象制作了外部对象的独立拷贝,就是深拷贝

引用和指针的语义是相似的,引用是不可改变的指针,指针是可以改变的引用。其实都是实现了引用语义。 深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。


无名对象初始化对象系统不会不调用拷贝构造函数。