c++ - 在菱形层次结构的中间,C++ 为什么需要指定虚拟继承?

  显示原文与译文双语对照的内容

我拥有类的菱形层次结构:


 A


/


 B C


 /


 D



为了避免D 中的两个副本,我们需要在B 和C 中使用虚拟继承。


class A { }; 


class B: virtual public A {};


class C: virtual public A { }; 


class D: public B, public C { }; 



问:为什么虚拟继承需要在B 和C 上执行,即使模糊性在D 中也是如这里。 如果它在D,它会更加直观。

为什么这里功能按标准委员会设计? 如果B 和C 类来自 3rd 方库,我们可以做什么?

编辑:我的答案是指B 和C 类,它们不应该在创建它的派生对象时调用构造函数。

时间: 原作者:

我不确定他们选择这种方式设计虚拟继承的原因,但我相信原因必须与对象布局相关。

假设 C++ 是以解决金刚石问题的方式设计的,你实际上将B 和C 继承在D 和C 中。 那么,B 和C的对象布局是什么? 如果没有人尝试实际继承,那么他们有自己的副本,可以使用标准的优化布局。 然而,如果某人没有从B 或者C 继承,那么对象布局就会不同,因为两者必须共享它们的副本,而不是继承。

这个问题是,当编译器首先看到B 和C 时,它不能知道是否要继承它们。 因这里,编译器必须返回在虚拟继承中使用的继承较慢的版本,而不是默认的继承版本。 这违背了"不要支付你不使用的东西"的C++ 原则( 开销原则 ),在那里你只为显式使用的语言功能支付。

原作者:
...