这里是新手 C++ 程序员。假设我有一个 Outer 类和一个 Inner 类嵌套。 Inner 包含一个指向 Outer 的指针成员,在构造期间设置。 Outer 包含一个函数 AddNewInner(),它创建一个指向自身的新 Inner 并将其添加到 vector 中。
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 添加到 vector 时,这可以正常工作。但是,当我尝试创建 Outer 实例的拷贝时,我遇到了一个问题:Outer 拷贝的 Inner vector 不指向拷贝(本身),它们仍然指向原始 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 vector 指向拷贝,而不是原始拷贝。完成此任务的最佳方法是什么,或者是否有其他方法可以完成相同的操作?
最佳答案
正确,这是预期的行为。当您在 C++ 中创建对象的拷贝时,编译器使用复制构造函数。如果您还没有为类编写自己的复制构造函数,那么它会使用编译器生成的复制构造函数,该构造函数只是依次为每个成员运行(可能生成的)复制构造函数。
因此,当复制 Outer
时,事件顺序如下:
- 编译器运行
Outer
的(生成的)复制构造函数 - 这将运行
std::vector
的复制构造函数。该构造函数为新 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++ 教科书中有关复制和赋值的内容:-)。
关于c++ - 如何复制具有嵌套类(包含指向外部类的指针成员)的类的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38560075/