我试图详细了解复制构造函数。这样做时,我做了下面的例子,
#include<iostream>
class Test
{
private:
int a;
public:
/*
Test(const Test &t) // User defined copy constructor
{
a = t.a;
} */
Test()
{
a = 120;
}
int display()
{
return a ;
}
void set(int var)
{
a = var;
}
};
int main()
{
Test t1;
std::cout << "t1.a " << t1.display() << std::endl;
Test t2 = t1; //Default copy constructor is called
std::cout << "T2.a " << t2.display() << std::endl;
t2.set(99); //Changing the value
std::cout << "t1.a " << t1.display() << std::endl;
std::cout << "T2.a " << t2.display() << std::endl;
return 0;
}
我在线阅读默认副本构造函数会进行“浅表复制”,所以这意味着,如果obj1 = obj2,即使分配后我在obj1或obj2中所做的更改 当它们指向同一位置时,需要在两个对象上均得到反映。 但是在这个例子中,当我更改一个对象的值时,它并没有反映在另一个对象中。使用用户定义的副本构造函数可获得相同的结果。
有人可以澄清这个话题吗,无论是否正在进行浅表复制!
谢谢!
答案 0 :(得分:3)
浅表副本不是您通常需要记住的特殊内容。相反,这仅仅是由于使用引用或指针而发生的事情。考虑以下示例:
struct foo {
int* x;
};
int a = 4;
foo f{&a};
此处x
指向a
,如果您复制f
,则新实例x
将指向相同的a
。多数民众赞成在浅表副本。一个深入的复制是要尊重不仅x
而且x
指向的内容是foo
的组成部分,并且也需要复制。通常,编译器无法决定您想要什么。 x
只是参考,还是x
所指的foo
的一部分?因此,您得到的是显而易见的:仅复制成员,而不复制它们可能引用的成员。
现在,如果您复制foo
,然后修改指向x
的值,那么它将修改相同的a
。进行了浅拷贝。以我的经验,“深层复制”和“浅层复制”这两个术语增加了混乱而不是清晰度。您免费获得的是所有成员都被复制(无论是浅副本还是深副本)。仅当您需要更多内容(还复制pointee)时,才需要担心浅层副本与深层副本。
TL; DR:您的示例中没有深层/浅层副本。对于值,这种区别是没有意义的。使用int*
来查看效果。
答案 1 :(得分:2)
我在线阅读默认副本构造函数会进行“浅拷贝”
这不是复制构造函数的正确思维方式。默认的复制构造函数只是复制类型中的任何成员,就像将复制构造函数依次应用于成员一样。
引用自:
如果未删除隐式声明的副本构造函数,则为 定义(即生成和编译函数主体) 编译器(如果已使用)。对于联合类型,隐式定义的副本 构造函数复制对象表示形式(如std :: memmove所示)。对于 非联合类类型(类和结构),构造函数执行 该对象的基础成员和非静态成员的完整成员级副本,位于 他们的初始化顺序,使用直接初始化。
因此,它实际上更像是深拷贝而不是浅拷贝。
答案 2 :(得分:1)
考虑将浅表副本复制为单纯的任务。所以,
Test t2 = t1;
表示
t2.a = t1.a
由于a
是int
,因此如果您从a
修改t1
,它将不会反映在t2
中。
因此,对于int
来说,浅表副本确实是深表副本。
考虑案例a
的类型为int*
。现在t2.a
和t1.a
都指向相同的存储位置。因此,如果您修改存储位置t1.a
上的值,由于t2.a
实际上指向相同的位置,因此也会通过UUU
反映出来。
答案 3 :(得分:0)
类的隐式定义的复制构造函数仅复制每个成员[class.copy.ctor]/14。复制成员基本上意味着,新对象的每个成员(被复制到其中的成员)都是从复制对象的相应成员中初始化的,就像编写相同的方式
T member(original.member);
其中T
是成员的类型,original
是要复制的对象。如果member
是类类型的,这实际上可以归结为调用T
的副本构造函数。但是,您的成员是普通的int
,不是类类型。没有要调用的副本构造函数(int
没有副本构造函数);简单地从原始对象的int
初始化新对象中的int
,归结为将原始int
的值复制到新的int
中... < / p>
您的编译器无法区分深拷贝与浅拷贝,甚至不知道“深拷贝”或“浅拷贝”的含义。在语言级别,C ++中没有深层副本或浅层副本。这些只是程序员常用的简单术语,用于讨论复制逻辑(但不是物理)包含其他对象的对象的不同方法……