【问题标题】:Default constructor in cpp shallow or deep copy?cpp浅拷贝或深拷贝中的默认构造函数?
【发布时间】:2018-12-26 14:39:36
【问题描述】:

默认的复制构造函数在 C++ 中是做浅拷贝还是深拷贝?

我真的对 cpp 中的默认复制构造函数感到困惑,因为它会进行浅复制或深复制,就像我做 v2=v1; 假设 v1={1,2,3} 时一样,现在如果我已经完成 v2[0]=1; 它没有得到反映,但我听说是做浅拷贝的,谁能解释一下?

【问题讨论】:

  • 请提供minimal reproducible example,我们不知道您的班级是什么样子
  • C++ 确实没有深拷贝或浅拷贝的概念,只有特定类的语义正确拷贝的概念。
  • @NeilButterworth 除非学术界介入。那么所有的赌注都没有了。
  • 默认的拷贝构造函数拷贝变量的内容,不多也不少。如果你有一个拷贝构造函数,那么拷贝构造函数中的代码就会被执行。

标签: c++ deep-copy shallow-copy


【解决方案1】:

你的问题是错误的问题。

首先,C++ 的默认复制/赋值是按成员的;它根据成员的行为递归地复制/分配。

精心设计的 C++ 类型在复制/分配时遵循一些模式,这些模式与 3 种不同的原始类型一致;值,引用amd指针语义。

值语义类型的行为类似于值。这大致对应于您的“深拷贝”。修改一个遵循值语义的变量永远不会改变另一个变量。 std::vector 是值语义类型,intdoublestd::string 和其他 std 容器类型也是如此。值语义是一种强大的模式,它使对程序行为的推理变得容易。请注意,值语义不需要实现为值;矢量通常实现为三组指针,构造/复制/等重载。

引用语义类型的行为类似于 C++ 引用类型 -- int&。这与 Java/C# 参考不同。 C++ 引用是别名; int& a=b; 表示 ab 的另一个名称。然后a=7 使ab 等于7。如果您有另一个引用 ca=c不会重新绑定 a 以引用 c;它将更改 a 所指的内容与 c 所指的值相同。

具有引用语义的复杂对象很少见。

指针语义类似于引用语义,但赋值重新绑定了它指向的对象。有时需要一个额外的操作,比如&,来创建一个新的指针。具有指针语义的类型包括std::reference_wrapperstd::string_viewstd::shared_ptr<double>gsl::span<char>int*

通常,在同一类型中混合具有不同语义的成员是一个坏主意; 0/3/5 规则指出,最好的移动/复制/分配/ctor/dtor 是空的。您的资源管理类型使用 RAII 并编写那些特殊成员,其他类型聚合它们。值语义类型不与引用/指针混合使用,以使复合类获得一致的语义。

TL;DR:这取决于。阅读有关您的成员的文档。记录您的类型所具有的语义,以便用户知道会发生什么。

但是请注意,引用语义与存储在 std 容器中是不兼容的。

【讨论】:

    【解决方案2】:

    隐式生成的复制构造函数(和赋值运算符)执行浅拷贝。

    值类型的浅拷贝和深拷贝没有区别。

    现在如果我已经完成 v2[0]=1;它没有得到反映

    除非v2 的类型是引用类型,否则没有理由期望此类操作得到反映

    【讨论】:

    • 这可能被否决了,因为对于不熟悉 C++ 具有具有值语义的复杂对象的能力的人来说不清楚。为了改进,我建议详细说明值/引用(和指针)语义,成员语义如何影响类型的默认语义,以及它如何流回深/浅概念。因为你说的一切都是真的,但我怀疑对所写的 OP 没有用处。嗯,也许我会回答。
    • 您说“值类型的浅拷贝和深拷贝没有区别”,这是什么意思?因为它们共享相同的内存(浅拷贝),因为这是赋值运算符。
    • @RobinKhurana 表示值类型的拷贝只有一种——对它们来说没有浅拷贝和深拷贝之分。 as they share the same memory什么共享内存?
    【解决方案3】:

    它也不行。它会进行 memberwise 副本。 IE。它使用复制构造函数复制类的所有成员。如果这些成员具有执行深拷贝的复制构造函数,那么您将获得深拷贝,如果他们执行浅拷贝,那么您将获得浅拷贝,或者他们可以完全执行其他操作。

    深拷贝和浅拷贝不是 C++ 的概念,相反,C++ 允许您根据需要进行深拷贝或浅拷贝。

    【讨论】:

    • 请注意,这意味着如果您的类包含一个指针,则该指针且仅复制该指针。您现在有两个对象指向同一事物。根据这个被指向的东西的所有权,这可能很糟糕。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多