Deep copy vs Shallow Copy
Possible Duplicate:
What is the difference between a deep copy and a shallow copy?
深拷贝和浅拷贝的区别是什么?复制构造函数做什么类型的复制?
浅拷贝:
副本的某些成员可能引用与原始对象相同的对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class X { private: int i; int *pi; public: X() : pi(new int) { } X(const X& copy) // <-- copy ctor : i(copy.i), pi(copy.pi) { } }; |
这里,原始和复制的
深拷贝:
原始的所有成员都被克隆(如果需要,可以递归地克隆)。没有共享对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class X { private: int i; int *pi; public: X() : pi(new int) { } X(const X& copy) // <-- copy ctor : i(copy.i), pi(new int(*copy.pi)) // <-- note this line in particular! { } }; |
此处,原始和复制的
The default copy constructor(which is automatically provided if you don't provide one yourself)creates only shallow copies.>strike>
Correction: Several comments below have correctly pointed out that it is wrong to say that the default copy constructor always performs a shallow copy (or a deep copy, for that matter). Whether a type's copy constructor creates a shallow copy, or deep copy, or something in-between the two, depends on the combination of each member's copy behaviour; a member's type's copy constructor can be made to do whatever it wants, after all.
下面是1998 C++标准中关于上述代码示例的第12.8节第8段:
The implicitly defined copy
constructor for classX performs a
memberwise copy of its subobjects.
[...] Each subobject is copied in the
manner appropriate to its type: [...]
[I]f the subobject is of scalar type,
the builtin assignment operator is
used.
最典型的例子是指向结构或对象(可变)的指针数组。
浅拷贝复制数组并维护对原始对象的引用。
深度复制也会复制(克隆)对象,因此它们与原始对象没有任何关系。这意味着对象本身被深度复制。这是一个困难的地方,因为没有真正的方法来知道某些东西是否被深度复制。
复制构造函数用于用以前创建的同一类的对象初始化新对象。默认情况下,编译器编写了一个浅副本。当不涉及动态内存分配时,浅拷贝工作得很好,因为当涉及动态内存分配时,两个对象将指向堆中的相同内存位置,因此为了消除此问题,我们编写了深拷贝,以便两个对象在内存中都有自己的属性副本。
为了阅读包含完整示例和解释的详细信息,您可以看到文章构造函数和析构函数。
默认的复制构造函数是Shallow。您可以根据需要使自己的复制构造函数变深或变浅。参见C++注释:OOP:复制构造函数。
深度复制实际上执行深度复制。这意味着,如果您的类有一些引用的字段,那么它们的值将被复制,而不是引用它们本身。例如,如果您有一个类的两个实例,即带有引用类型字段的A&B,并执行深度复制,则在A中更改该字段的值不会影响B中的值,反之亦然。浅复制的情况不同,因为只复制引用,因此在复制的对象中更改此字段将影响原始对象。
What type of a copy does a copy constructor does?
它依赖于实现。这意味着没有严格的规则,您可以像深拷贝或浅拷贝那样实现它,但是据我所知,在复制构造函数中实现深拷贝是一种常见的做法。但是,默认的复制构造函数执行一个浅复制。