class A { public: void eat(){ cout<<"A";} };
class B: virtual public A { public: void eat(){ cout<<"B";} };
class C: virtual public A { public: void eat(){ cout<<"C";} };
class D: public B,C { public: void eat(){ cout<<"D";} };
int main(){
A *a = new D();
a->eat();
}
我理解钻石问题,上面的代码没有这个问题。
虚拟继承到底是如何解决问题的呢?
我的理解是:当我说A *a = new D();
,编译器想知道类型的对象是否D
可以分配给类型的指针A
,但它有两条可以遵循的路径,但不能自行决定。
那么,虚拟继承如何解决这个问题(帮助编译器做出决定)?
你要:(可通过虚拟继承实现)
A
/ \
B C
\ /
D
And not:(没有虚拟继承会发生什么)
A A
| |
B C
\ /
D
虚拟继承意味着只有 1 个基类实例A
类不是 2。
你的类型D
将有 2 个 vtable 指针(您可以在第一个图中看到它们),一个用于B
和一个用于C
实际上继承的人A
. D
的对象大小增加了,因为它现在存储了 2 个指针;然而只有一个A
now.
So B::A
and C::A
是相同的,因此不会有任何含糊的调用D
。如果您不使用虚拟继承,您将看到上面的第二张图。然后,对 A 成员的任何调用都会变得不明确,您需要指定要采用的路径。
维基百科在这里有另一个很好的概述和例子 http://en.wikipedia.org/wiki/Virtual_inheritance
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)