struct B { int i; };
struct D1 : virtual B {};
struct D2 : B {}; // <-- not virtual
struct DD : D1, D2 {};
上面编码后,编译器仍然要求D2
为virtual
:
DD d;
d.i = 0; // error: request for member `i' is ambiguous
我不明白的是,一旦你提示编译器B
virtual
是DD
(D1
),那么为什么它仍然i
1}}含糊不清?
(如果我的记忆服务正确,那么旧的VC ++(2006年)就足以用单virtual
个继承来证明这一点
答案 0 :(得分:7)
B对于DD不是虚拟的 - 它相对于D1是虚拟的。在创建D2时,它包含B的完整副本。所以现在DD有两个B实现:一个作为D2的一部分,一个作为结尾(由D1指向)。有i
的两份副本,使用它确实含糊不清。
如果D2也使用虚拟继承,而不是包含B的副本,它将包含指向D1也指向的B实例的指针,而DD只包含一个B实例。
我将尝试说明内存布局,希望这是正确的......:
你的情况,有一个虚拟继承和一个非虚拟 -
| D1 | D2 + B | B |
+--+-------+----------+---------+
| vptr to B ^
+-----------------------|
让D1和D2都虚拟地继承 -
| D1 | D2 | B |
+--+-----+---+----+-------+
| | ^
+---------+---------|
答案 1 :(得分:2)
您必须阅读Diamond problem。在方法标题下,对于CPP,您的案例被明确提及,您的观察与那里解释的一致。
答案 2 :(得分:2)
该标准要求d.i
在这种情况下必须含糊不清。 ISO / IEC 14882:2003第10.1.6节涵盖了具有给定类型的虚拟和非虚拟基类的类。