为什么需要在菱形层次结构中间指定虚拟继承? [英] Why does virtual inheritance need to be specified in the middle of a diamond hierarchy?

查看:262
本文介绍了为什么需要在菱形层次结构中间指定虚拟继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类别的钻石层次结构:

  A 
/ \
BC
\ /
D

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

  class A {}; 
class B:virtual public A {};
class C:virtual public A {};
class D:public B,public C {};问题:为什么需要在B和C上执行虚拟继承,即使歧义是在B和C上执行的? D?这将是更直观的,如果它是在D。



为什么这个功能由标准委员会这样设计?
如果B和C类都来自第三方库,我们能做什么?



编辑:我的答案是指示B和C类,他们不应该

解决方案

我不确定是什么时候创建它的派生对象他们选择以这种方式设计虚拟继承的确切原因,但我相信原因与对象布局有关。



假设C ++的设计方式,钻石问题,你将在D中虚拟地继承B和C,而不是在B和C中虚拟地继承A.现在,B和C的对象布局是什么?好吧,如果没有人试图从它们虚拟继承,那么他们每个都有自己的A副本,并且可以使用标准的优化布局,其中B和C在它们的基础上各有一个A.但是,如果有人确实继承了B或C,那么对象布局必须不同,因为两者必须共享它们的副本。



这样做的问题是,当编译器首先看到B和C时,它不能知道是否有人要从它们继承。因此,编译器将不得不回退在虚拟继承中使用的较慢版本的继承,而不是默认情况下开启的更优化的继承版本。这违反了不支付您不使用的的C ++原则(零开销原则),其中您只需支付您明确使用的语言功能。


I have diamond hierarchy of classes:

    A
  /   \
 B     C
  \   /
    D

To avoid two copies of A in D, we need to use virtual inheritance at B and C.

class A                     {  }; 
class B: virtual public A {};
class C: virtual public A   { }; 
class D: public B, public C { }; 

Question: Why does virtual inheritance needs to be performed at B and C, even though the ambiguity is at D? It would have been more intuitive if it is at D.

Why is this feature designed like this by standards committee? What can we do if B and C classes are coming from 3rd party library ?

EDIT: My answer was to indicate B and C classes that they should not invoke A's constructor whenever its derived object gets created, as it will be invoked by D.

解决方案

I'm not sure of the exact reason they chose to design virtual inheritance this way, but I believe the reason has to do with object layout.

Suppose that C++ was designed in a way where to resolve the diamond problem, you would virtually inherit B and C in D rather than virtually inheriting A in B and C. Now, what would the object layout for B and C be? Well, if no one ever tries to virtually inherit from them, then they'd each have their own copy of A and could use the standard, optimized layout where B and C each have an A at their base. However, if someone does virtually inherit from either B or C, then the object layout would have to be different because the two would have to share their copy of A.

The problem with this is that when the compiler first sees B and C, it can't know if anyone is going to be inheriting from them. Consequently, the compiler would have to fall back on the slower version of inheritance used in virtual inheritance rather than the more optimized version of inheritance that is turned on by default. This violates the C++ principle of "don't pay what you don't use for," (the zero-overhead principle) where you only pay for language features you explicitly use.

这篇关于为什么需要在菱形层次结构中间指定虚拟继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆