关于c ++:深拷贝与浅拷贝

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)
    { }
};

这里,原始和复制的X对象的pi成员都指向同一个int

深拷贝:

原始的所有成员都被克隆(如果需要,可以递归地克隆)。没有共享对象:

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!
    { }
};

此处,原始和复制的X对象的pi成员将指向不同的int对象,但这两个对象的值相同。

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 class X 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?

它依赖于实现。这意味着没有严格的规则,您可以像深拷贝或浅拷贝那样实现它,但是据我所知,在复制构造函数中实现深拷贝是一种常见的做法。但是,默认的复制构造函数执行一个浅复制。