如果对象A包含成员对象B并且对象B具有指向其父对象A的指针,是否需要为对象B指定复制构造函数?
假设没有动态分配.
此外,3规则适用于此吗?
最佳答案 您的设计使用双向导航实现合成.这完全有效.
然而,正如谢尔盖在评论中指出的那样,这样的设计并非没有问题.
假设您有一个Object类和一个包含Object的类Container.这里有一些基本问题:
Container c;
Object mo1; // Q1: should this be valid ? (i.e. is an object without parent allowed
Object mo2 = c.o; // Q2: is this acceptable ? Q3: Who is parent of mo2 ?
看看问题Q2和Q3:如果这样的初始化是可以接受的,那么直接的问题是你想要的父母:
>如果mo2应该没有父级,则需要根据3的规则使用复制构造函数来清除父级.
>如果mo2应引用同一个父级(尽管它不是成员),则可以保留默认的复制构造函数.
例:
struct Container;
struct Object{
Container *parent;
Object (Container *p=nullptr) : parent(p) { cout << "construct object"<<endl; }
// copy constructor or compiler generated one depending on Q2+Q3
~Object() {}
...
};
struct Container {
Object o;
Container() : o(this) {}
};
如果不能接受这样的初始化,则应该在代码中明确禁止复制构造.
Object (const Object &o) = delete;
重要说明:Container可能还需要一个复制构造函数.无论您决定使用Object,如果必须是可复制的,您可能必须在Container中处理.你决不能在那里使用Object的拷贝构造函数.
重要说明2:Container本身可用于更复杂的情况.以矢量< Container>为例.将新容器添加到向量时,可能会执行重定位,如果您没有提供注意的Container复制构造函数,则可能会使指针无效!