深拷贝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