【问题标题】:Deep Copying in C++C++ 中的深度复制
【发布时间】:2015-02-28 13:22:03
【问题描述】:

在 C++ 中考虑这两种情况,

  1. 通过引用返回对象。
  2. 按原样返回对象。

在上述哪种情况下进行了深度复制,为什么?

提前致谢。

【问题讨论】:

  • 返回引用不会复制。返回对象使用其复制构造函数。是否进行深拷贝取决于它的编写方式。
  • 这些方法本质上都不是深度复制。如果类有一个适当的复制构造函数来进行实际的深度复制,则按值返回可以进行深度复制。
  • @Barmar 取决于什么?你能举个例子吗,或者你能指导我应该读什么来更好地理解吗?
  • 这取决于复制构造函数和赋值运算符是复制它所指向的所有对象还是只复制指针。
  • 如果您了解什么是深度复制,那么它所依赖的内容应该很明显了。所以也许你需要回到书本上去研究这个概念。

标签: c++ deep-copy


【解决方案1】:

当一个对象通过引用返回时,没有对象的复制。

当一个对象按值返回时,将进行复制。是浅拷贝还是深拷贝取决于拷贝构造函数。

示例 1

简单struct:

struct Point
{
    double x;
    double y;
    double z;
};

您不需要为这样的struct 实现复制构造函数。编译器将为它生成一个正确工作的复制构造函数。

示例 2

struct Edge;

struct Vertex
{
    std::list<Edge*> edges;
};

对于Vertex,编译器生成的复制构造函数会复制Edges的列表。发生这种情况是因为std::list 的复制构造函数进行了深层复制。然而,深拷贝到此为止。在制作Vertex 的副本时,它不会创建新的Edge 对象。如果这还不够,您必须为Vertex 实现一个复制构造函数,并根据您的需要做正确的事情。

【讨论】:

    【解决方案2】:

    如果一个对象有指向动态分配内存的指针,并且在复制原始对象时需要复制动态分配的内存,那么就需要进行深拷贝。

    需要深拷贝的类一般需要:

    1. 用于进行初始分配或将指针设置为 NULL 的构造函数。
    2. 用于删除动态分配的内存的析构函数。
    3. 用于复制动态分配的内存的复制构造函数。
    4. 一个重载的赋值运算符,用于复制动态分配的内存。

    要进行深拷贝,必须编写拷贝构造函数并重载赋值运算符,否则拷贝会指向原来的,后果不堪设想。

    阅读更多信息 - Shallow vs. deep copyingHow and When to Make Deep Copies in C++

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-08
      • 2017-04-09
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      相关资源
      最近更新 更多