sta*_*ica 53
浅拷贝:
副本的某些成员可能引用与原始对象相同的对象:
class X
{
private:
int i;
int *pi;
public:
X()
: pi(new int)
{ }
X(const X& copy) // <-- copy ctor
: i(copy.i), pi(copy.pi)
{ }
};
Run Code Online (Sandbox Code Playgroud)
这里,pi
原始和复制X
对象的成员都指向相同的成员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!
{ }
};
Run Code Online (Sandbox Code Playgroud)
这里,pi
原始和复制X
对象的成员将指向不同的int
对象,但这两个对象具有相同的值.
默认的复制构造函数(如果您不自己提供,则自动提供)仅创建浅拷贝.
更正:下面的几条评论正确地指出,说默认的复制构造函数总是执行浅拷贝(或者深层拷贝,就此而言)是错误的.类型的复制构造函数是创建浅拷贝,还是深拷贝,还是两者之间的某种东西,取决于每个成员的复制行为的组合; 毕竟,成员的类型的复制构造函数可以做任何想做的事情.
以下是1998年C++标准第12.8节第8段关于上述代码示例的内容:
类的隐式定义的复制构造函数
X
执行其子对象的成员复制.[...]每个子对象都以适合其类型的方式复制:[...] [I]如果子对象是标量类型,则使用内置赋值运算符.
cle*_*tus 12
这个典型的例子是一个指向结构或对象的指针数组(这是可变的).
一个浅拷贝复制阵列,并保持原来的对象的引用.
一个深拷贝,使他们没有承担相对于原始将复制(克隆)的对象了.隐含在这里的是对象本身被深层复制.这是它变得艰难的地方,因为没有真正的方法可以知道某些东西是否被深层复制.
复制构造函数用于使用先前创建的同一类对象初始化新对象.默认情况下编译器写了一个浅拷贝.当不涉及动态内存分配时,浅拷贝工作正常,因为当涉及动态内存分配时,两个对象将指向堆中的相同内存位置.因此,为了消除此问题,我们编写了深层副本,因此两个对象都有自己的属性副本在记忆中.
为了通过完整的示例和解释阅读详细信息,您可以看到文章构造函数和析构函数.
默认的复制构造函数很浅.您可以根据需要将自己的复制构造函数设置为深或浅.请参阅C++注释:OOP:复制构造函数.