对于虚拟继承,最派生对象的义务不仅是初始化直接基类,还初始化所有 virtual
祖先类。
例如,考虑以下类层次结构(注意 struct
默认使用 public
继承):
struct B {
B() = delete;
B(int);
};
struct D1 : virtual B {
D1(int x) : B(x) {}
};
struct D2 : virtual B {
D2(int x) : B(x) {}
};
如果我要引入这样的 D12
类...
struct D12 : D1, D2 {
D12(int x) : D1(x), D2(x) {}
};
编译会失败,因为 D12
必须初始化 B
并且因为它没有这样做,编译器假定应该调用默认构造函数(已删除)。解决方案是手动调用 B::B(int)
构造函数:
struct D12 : D1, D2 {
D12(int x) : B(x), D1(x), D2(x) {}
};
我发现该解决方案存在问题。问题是类 D1
的声明不包含 B
或 virtual
。为了正确实现这个类,我们必须以某种方式知道类 D1
和 D2
继承自虚拟基类 B
。可以说应该假设如果我们使用多重继承,那么我们将不得不初始化一些虚拟基类。然而,当似乎只使用常规继承时,问题仍然存在:
struct D : D1 {
// D still has to initialize B
D(int x) : B(x), D1(x) {}
};
作为一种解决方法,我想也许我可以让 D
也继承自 B
(实际上)以至少在声明中表达这种隐藏的依赖:
struct D : virtual B, D1 {
D(int x) : B(x), D1(x) {}
};
这是否保证等同于之前的代码?这个问题有没有更好的解决方案?