虚拟继承如何解决“钻石"问题?(多重继承)歧义?

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::AC::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.

维基百科有另一个很好的纲要和例子

这篇关于虚拟继承如何解决“钻石"问题?(多重继承)歧义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Prevent class inheritance in C++(防止 C++ 中的类继承)
Why should I declare a virtual destructor for an abstract class in C++?(为什么要在 C++ 中为抽象类声明虚拟析构函数?)
Why is Default constructor called in virtual inheritance?(为什么在虚拟继承中调用默认构造函数?)
C++ cast to derived class(C++ 转换为派生类)
C++ virtual function return type(C++虚函数返回类型)
Is there any real risk to deriving from the C++ STL containers?(从 C++ STL 容器派生是否有任何真正的风险?)