How does virtual inheritance solve the quot;diamondquot; (multiple inheritance) ambiguity?(虚拟继承如何解决“钻石问题?(多重继承)歧义?)
问题描述
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();
}
我理解钻石问题,上面的代码没有这个问题.
I understand the diamond problem, and above piece of code does not have that problem.
虚拟继承究竟是如何解决问题的?
How exactly does virtual inheritance solve the problem?
我的理解:当我说 A *a = new D();
时,编译器想知道是否可以将 D
类型的对象分配给 A 类型的指针
,但它有两条路径可以走,但不能自己决定.
What I understand:
When I say A *a = new D();
, the compiler wants to know if an object of type D
can be assigned to a pointer of type A
, but it has two paths that it can follow, but cannot decide by itself.
那么,虚拟继承是如何解决这个问题的(帮助编译器做出决定)?
So, how does virtual inheritance resolve the issue (help compiler take the decision)?
推荐答案
您想要:(可通过虚拟继承实现)
You want: (Achievable with virtual inheritance)
A
/
B C
/
D
而不是:(没有虚拟继承会发生什么)
And not: (What happens without virtual inheritance)
A A
| |
B C
/
D
虚拟继承意味着只有 1 个 A
基类的实例,而不是 2 个.
Virtual inheritance means that there will be only 1 instance of the base A
class not 2.
您的类型 D
将有 2 个 vtable 指针(您可以在第一个图中看到它们),一个用于 B
,一个用于 C
他们实际上继承了A
.D
的对象大小增加了,因为它现在存储了 2 个指针;但是现在只有一个A
.
Your type D
would have 2 vtable pointers (you can see them in the first diagram), one for B
and one for C
who virtually inherit A
. D
's object size is increased because it stores 2 pointers now; however there is only one A
now.
所以 B::A
和 C::A
是相同的,所以不会有来自 D
的歧义调用.如果你不使用虚拟继承,你有上面的第二个图.任何对 A 成员的调用都会变得模棱两可,您需要指定要采用的路径.
So B::A
and C::A
are the same and so there can be no ambiguous calls from D
. If you don't use virtual inheritance you have the second diagram above. And any call to a member of A then becomes ambiguous and you need to specify which path you want to take.
维基百科有另一个很好的纲要和例子
这篇关于虚拟继承如何解决“钻石"问题?(多重继承)歧义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:虚拟继承如何解决“钻石"问题?(多重继承)歧
基础教程推荐
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01