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
而不是:(没有虚拟继承会发生什么)
A A
| |
B C
\ /
D
虚拟继承意味着基础A
类的实例只有1个,而不是2个。
您的类型 D
将有 2 个 vtable 指针(您可以在第一张图中看到它们),一个用于 B
,一个用于 C
谁实际上继承了 A
。 D
的对象大小增加了,因为它现在存储了 2 个指针;但是现在只有一个A
。
所以 B::A
和 C::A
是相同的,所以不会有来自 D
的模棱两可的调用。如果你不使用虚拟继承,你有上面的第二张图。任何对 A 成员的调用都会变得模棱两可,您需要指定要采用的路径。
关于c++ - 虚拟继承如何解决 "diamond"(多重继承)的歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2659116/