默认的复制构造函数是否在C ++中执行浅拷贝或深拷贝?
我真的对cpp中的默认复制构造函数感到困惑,因为它会做浅复制或深复制,就像我select
columnA,
sum(case when columnA <> '' and data_set = 1234 then 1 else 0 end) as PREVIOUS_COUNT,
sum(case when columnA <> '' and data_set = 4321 then 1 else 0 end) as CURRENT_COUNT
from myTable1
where data_set in (1234, 4321)
group by columnA
order by columnA ASC;
假设v2=v1;
的时候一样,现在如果我已经完成v1={1,2,3}
了没有得到反映,但我听说它做了浅表抄本,有人可以解释吗?
答案 0 :(得分:7)
它也不做。它会执行 memberwise 副本。即它使用其复制构造函数复制该类的所有成员。如果这些成员具有执行深层复制的副本构造函数,则将获得深层副本;如果他们进行浅层复制,则将获得浅层副本,或者他们可以完全执行其他操作。
深层复制和浅层复制不是C ++概念,而是C ++使您可以根据需要进行深层或浅层复制。
答案 1 :(得分:1)
您的问题是错误的问题。
首先,C ++默认复制/分配是成员方式的;它根据成员的操作递归地复制/分配。
精心设计的C ++类型在复制/分配时遵循几种模式,并排列了3种不同的原始类型。值,请参考amd指针语义。
值语义类型的行为类似于值。这大致相当于您的“深层副本”。遵循值语义修改一个变量永远不会更改另一个变量。 std::vector
是一种值语义类型,int
,double
,std::string
和其他std
容器类型也是如此。值语义是一种强大的模式,它使对程序行为的推理变得容易。注意,值语义不必实现为值。向量通常以三重指针的形式实现,并具有过度的构造/复制/等作用。
引用语义类型的行为类似于C ++引用类型-int&
。这与Java / C#参考不同。 C ++引用是别名。 int& a=b;
表示a
是b
的另一个名称。然后a=7
使a
和b
等于7
。如果您还有另一个引用c
,则a=c
将不重新绑定a
来引用c
;它将更改a
所引用的值与c
所引用的值。
具有引用语义的复杂对象很少。
指针语义类似于引用语义,但是赋值重新绑定了它指向的对象。有时需要额外的操作,例如&
,以创建新的指针。具有指针语义的类型包括std::reference_wrapper
,std::string_view
,std::shared_ptr<double>
,gsl::span<char>
和int*
。
通常,将具有不同语义的成员混合在同一类型中是一个坏主意; 0/3/5规则指出最佳移动/复制/关联/ ctor / dtor是空的。您的资源管理类型使用RAII并编写那些特殊成员,其他类型则将它们聚集在一起。值语义类型不与引用/指针混合使用,以使复合类获得连贯的语义。
TL; DR:取决于。阅读您会员的文档。记录您的类型具有哪些语义,以便用户知道期望的内容。
但是请注意,引用语义与存储在std容器中不兼容。
答案 2 :(得分:-1)
隐式生成的副本构造函数(和赋值运算符)执行浅表副本。
值类型的浅表副本和深表副本之间没有区别。
现在是否已经完成v2 [0] = 1;它没有得到体现
除非v2
的类型是引用类型,否则没有理由期望这种操作得到反映。