深拷贝vs浅拷贝

可能重复:
深拷贝和浅拷贝之间有什么区别?

深浅拷贝有什么区别? 拷贝构造函数做什么类型的拷贝?


浅拷贝:

该副本的某些成员可能会引用与原始相同的对象:

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


深层复制:

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

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对象,但这两个对象都具有相同的值。


默认的复制构造函数(如果您自己不提供自动提供的,将自动提供)只创建浅拷贝。

更正:下面的几条评论已经正确地指出,说缺省拷贝构造函数总是执行浅拷贝(或者深层拷贝)是错误的。 一个类型的拷贝构造函数是创建一个浅拷贝还是深拷贝, 还是两者之间的内容都取决于每个成员拷贝行为的组合; 毕竟,一个成员的类型的拷贝构造函数可以做任何想做的事情。

以下是1998年C ++标准第12.8节第8段关于上述代码示例的内容:

X的隐式定义的复制构造函数执行其子对象的成员副本。 [...]每个子对象都以适合其类型的方式复制:[...]如果子对象是标量类型,则使用内置赋值运算符。


这个的典型例子是指向结构体或对象(可变的)的指针数组。

浅拷贝复制数组并保持对原始对象的引用。

深层复制也会复制(克隆)这些对象,因此它们与原始文件无关。 隐含的是,对象本身被深度复制。 这是它变得困难的地方,因为没有真正的方法可以知道是否复制了某些内容。

复制构造函数用于使用先前创建的同一类的对象来初始化新对象。 默认情况下编译器写了一个浅拷贝。 浅拷贝在没有涉及动态内存分配时工作正常,因为当涉及动态内存分配时,两个对象将指向堆中的同一内存位置。因此,为了消除这个问题,我们写了深拷贝,因此两个对象都有自己的属性副本在记忆中。

为了阅读完整的例子和解释的细节,你可以看到文章构造函数和析构函数。

默认的复制构造函数很浅。 您可以根据需要制作自己的拷贝构造函数。 请参阅C ++注释:OOP:复制构造函数。


深层复制从字面上执行深层复制。 这意味着,如果你的类有一些引用的字段,它们的值将被复制,而不是引用它们自己。 例如,如果您有两个类的实例,A和B带有引用类型的字段并执行深度复制,则在A中更改该字段的值不会影响B中的值,反之亦然。 事情与浅拷贝不同,因为只有引用被复制,因此,在复制对象中更改此字段会影响原始对象。

拷贝构造函数做什么类型的拷贝?

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

链接地址: http://www.djcxy.com/p/79349.html

上一篇: Deep copy vs Shallow Copy

下一篇: Thread scheduler in java with single CPU?