什么情况下使⽤浅拷贝什么时候使⽤深拷贝?
好诗好词Q:什么是浅拷贝(shallow copy)和深拷贝(deep copy)?
A:
浅拷贝就是成员数据之间的⼀⼀赋值:把值赋给⼀⼀赋给要拷贝的值。但是可能会有这样的情况:对象还包含资源,这⾥的资源可以值堆资源,或者⼀个⽂件。。当值拷贝的时候,两个对象就有⽤共同的资源,同时对资源可以访问,这样就会出问题。深拷贝就是⽤来解决这样的问题的,它把资源也赋值⼀次,使对象拥有不同的资源,但资源的内容是⼀样的。对于堆资源来说,就是在开辟⼀⽚堆内存,把原来的内容拷贝。
如果你拷贝的对象中引⽤了某个外部的内容(⽐如分配在堆上的数据),那么在拷贝这个对象的时候,让新旧两个对象指向同⼀个外部的内容,就是浅拷贝;如果在拷贝这个对象的时候为新对象制作了外部对象的独⽴拷贝,就是深拷贝
精诚所至金石为开引⽤和指针的语义是相似的,引⽤是不可改变的指针,指针是可以改变的引⽤。其实都是实现了引⽤语义。
深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引⽤的时候,当拷贝⼀个对象时,如果需要拷贝
这个对象引⽤的对象,则是深拷贝,否则是浅拷贝。
COW语义是“深拷贝”与“推迟计算”的组合,仍然是深拷贝,⽽⾮浅拷贝,因为拷贝之后的两个对象的数据在逻辑上是不相关的,只是内容相同。
============================================================================
Q:什么情况下使⽤浅拷贝什么时候使⽤深拷贝?
A:
⽆论深浅,都是需要的。当深拷贝发⽣时,通常表明存在着⼀个“聚合关系”,⽽浅拷贝发⽣时,通常表明存在着⼀个“相识关系”。
举个简单的例⼦:旅游项目策划
当你实现⼀个Composite Pattern,你通常都会实现⼀个深拷贝(如果需要拷贝的话),很少有要求同的Composite共享Leaf的;
⽽当你实现⼀个Obrver Pattern时,如果你需要拷贝Obrver,你⼤概不会去拷贝Subject,这时就要实现个浅拷贝。
陈晓旭为什么要出家是深拷贝还是浅拷贝,并不是取决于时间效率、空间效率或是语⾔等等,⽽是取决于哪⼀个是逻辑上正确的。
联合中心球馆事必躬亲=============================================================================
Q:在C++中default constructor对对象进⾏的是怎样的拷贝动作?
A:
再纠正⼀个概念:default constructor是不负责拷贝动作的,我想你说的应该是指implicitly-declared copy constructor。它会调⽤所有直系基类的copy constructor和有成员的copy constructor,并且复制vtpr。如果⼀个类:
1:没有虚⽅法和虚基类
意大利比萨斜塔2:所有直系基类的copy constructor都是⽆代价的
3:所有成员的copy constructor都是⽆代价的
这时它的copy constructor是⽆代价的,相当于⽤memcpy实现。
消除贫困
判断它是深拷贝还是浅拷贝,还是要根据类的实现。⽐如如果它有⼀个⽤原⽣指针指针实现的对象引⽤,或是⽤boost::shared_ptr等引⽤分享所有权的智能指针实现的对象引⽤,则这个拷贝是浅拷贝;如果是⽤copy_ptr这种实现了深拷贝的智能指针实现的对象引⽤,就是深拷贝了。