如何将包含指针成员的嵌套类复制到类的实例到外部类?

时间:2016-07-25 05:04:36

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

新手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()以向向量添加Inners时工作正常。但是,当我尝试创建Outer实例的副本时,我遇到了一个问题:外部副本的Inners向量不指向副本(本身),它们仍然指向原始外部。

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矢量指向副本,而不是原始副本。什么是实现这一目标的最佳方式,或者是否有其他方法可以做同样的事情?

2 个答案:

答案 0 :(得分:0)

您需要为您的班级使用自定义copy constructor/assignment operator。这样您就可以制作Outer* mOuterParent变量的深层副本;可能会创建一个新的。

复制指针时,您正在复制指向内存中特定地址空间的变量。仅复制指针使您能够访问相同的真正变量&#39;通过两个访问变量&#39;。

在您的示例中,特定Outer* mOuterParent对象的outer变量将始终指向该指针指向的outer类的相同实例化无论你制作了多少份特定物品。

答案 1 :(得分:0)

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

因此,在复制Outer时,事件序列如下:

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

为了在复制Inner时更新Outer元素,您需要为Outer编写自定义复制构造函数,以便按照您的喜好更新指针。像这样:

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

请注意,无论何时编写自定义复制构造函数,您几乎总是需要编写自定义赋值运算符。我建议您阅读自己喜爱的C ++教科书中的复制和作业: - )。