【问题标题】:How do I copy an instance of a class with a nested class containing a pointer member to the outer class?如何复制具有包含指向外部类的指针成员的嵌套类的类的实例?
【发布时间】:2016-07-25 05:04:36
【问题描述】:

这里是 C++ 程序员新手。假设我有一个带有嵌套类 Inner 的类 Outer。 Inner 包含一个指针成员,在构造期间设置,指向 Outer。 Outer 包含一个函数 AddNewInner(),它创建一个指向自身的新 Inner 并将其添加到向量中。

class Outer {

public:

    class Inner {
    public:
        Inner(Outer* outerParent) : mOuterParent(outerParent) {}
        Outer* mOuterParent;
    }

    void AddNewInner() {
        Inner newInner(this);
        mInnersVec.push_back(newInner);
    }

    vector<Inner> mInnersVec;
}

在创建 Outer 的新实例并调用 AddNewInner() 将 Inner 添加到向量时,这可以正常工作。但是,当我尝试创建 Outer 实例的副本时遇到了一个问题:Inner 的 Outer 副本的向量不指向副本(本身),它们仍然指向原始的 Outer。

Outer outerA;
outerA.AddNewInner(); 
Outer* ptrA = outerA.mInnersVec[0].mOuterParent; // this points to outerA, good!

Outer outerB = outerA;
Outer* ptrB = outerB.mInnersVec[0].mOuterParent; // this still points to outerA, bad!

我需要副本中的 Inners 向量指向副本,而不是原始。完成此操作的最佳方法是什么,或者是否有其他方法可以做同样的事情?

【问题讨论】:

  • 啊....您需要阅读复制构造函数。谷歌拷贝构造函数,深拷贝,浅拷贝。有很多参考资料。

标签: c++ pointers copy inner-classes outer-classes


【解决方案1】:

正确,这是预期的行为。当您在 C++ 中创建对象的副本时,编译器使用 复制构造函数。如果您还没有为一个类编写自己的复制构造函数,那么它使用编译器生成的复制构造函数,它只是依次为每个成员运行(可能生成的)复制构造函数。

所以当复制Outer 时,事件的顺序是这样的:

  • 编译器为Outer 运行(生成的)复制构造函数
  • 这将为std::vector 运行复制构造函数。此构造函数为新向量分配存储空间,然后依次为每个元素运行复制构造函数
  • 因此,Inner 的(生成的)复制构造函数针对每个元素运行,它只是复制成员指针(仍然指向原始的 Outer)。

为了在复制Outer 时更新Inner 元素,您需要为Outer 编写一个自定义复制构造函数,它可以根据需要更新指针。像这样:

Outer::Outer(const Outer& other)
    : mInnersVec(other.mInnersVec) // Do initial vector copy
{
    // Update vector elements
    for (auto& elem : mInnersVec) {
       elem.mOuterParent = this;
    }
}

请注意,每当您编写自定义复制构造函数时,您几乎总是需要编写自定义赋值运算符。我建议您阅读您最喜欢的 C++ 教科书中有关复制和分配的内容:-)。

【讨论】:

    【解决方案2】:

    您需要为您的班级使用自定义copy constructor/assignment operator。这将允许您对 Outer* mOuterParent 变量进行深层复制;可能会创建一个新的。

    当你复制一个指针时,你是在复制一个指向内存中特定地址空间的变量。复制指针仅使您能够通过两个“访问器变量”访问相同的“真实变量”。

    在您的示例中,特定 outer 对象的 Outer* mOuterParent 变量将始终指向该指针所指向的 outer 类的相同实例,无论该类有多少副本您制作的特定对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      相关资源
      最近更新 更多