我认为一个例子会最好地描述我的问题。
struct Base {
Base() = delete;
Base(int x) : x(x) {}
int x;
};
struct Derived1 : virtual Base {
Derived1(int y) : Base(5), y(y) {}
int y;
};
struct Derived2 : virtual Base {
Derived2(int z) : Base(10), z(z) {}
int z;
};
struct Derived3: Derived1, Derived2 {
public:
Derived3(int y, int z) : Derived1(y), Derived2(z) {}
};
我得到一个错误:
In constructor ‘Derived3::Derived3(int, int)’:
error: use of deleted function ‘Base::Base()’
Derived3(int y, int z) : Derived1(y), Derived2(z) {}
我不明白为什么会出现这种错误。在我看来,所有基类实际上都是通过它们的构造函数(显式Derived1
和Derived2
以及隐式Base
到Derived2
初始化的(我不确定这里,也许通过Derived1
))。
好吧,让我们做编译器告诉我的事情。
struct Derived3: Derived1, Derived2 {
public:
Derived3(int y, int z) : Base(-1), Derived1(y), Derived2(z) {}
};
它编译,如果我现在这样做:
Derived3 d = Derived3(7, 9);
std::cout << d.x << std::endl;
std::cout << d.y << std::endl;
std::cout << d.z << std::endl;
我得到-1, 7, 9
。而这根本不是我想要的。一个想法是用它的一个派生类初始化基类,我期望第一个数字是5或10.
所以,这是我的问题:
为什么在其中一个派生类中已经完成它时,我被迫显式调用Base
构造函数?
更具体地说,由于我有多重继承和虚拟继承,我相信Derived3
的任何实例都只有Base
类实例的一个副本。我期待Base
的这个副本在其最派生的类(Derived1
或Derived2
)中初始化,但是我清楚地看到它不能以这种方式工作= (我哪里错了?
答案 0 :(得分:4)
使用虚拟继承时,只有1个Base副本。谁应该初始化该副本,Derived 1或Derived 2?没有办法知道。这就是为什么你被迫在Derived 3中自己做,所以没有歧义。这也是你获得输出而不是5或10的原因。
如果没有虚拟继承,Derived 1和Derived 2都将拥有自己负责的Base副本,因此没有歧义。当你强制它们从同一个基础继承时,Derived 3必须取得Base的所有权才能解决歧义...虚拟继承充其量是奇怪的。