虚继承

75

"虚拟继承"的含义是什么?

我看到了以下代码,但不理解在下面的上下文中关键字virtual的含义:

class A {};
class B : public virtual A;

1
看看这个(之前已经有人问过了):https://dev59.com/TXVD5IYBdhLWcg3wTZ1m - OJ.
1个回答

57

虚继承被用于解决DDD问题(派生出的恐怖钻石问题)。

看下面的例子,其中有两个类都继承自同一个基类:

class Base
{

public:

 virtual void  Ambig();

};

class C : public Base
{

public:

//...

};

class D : public Base
{
public:

    //...

};
现在,您想创建一个新类,该类继承自C和D类(这两个类都继承了Base :: Ambig()函数):
class Wrong : public C, public D
{

public:

...

};

虽然您在上面定义了"Wrong"类,但实际上您创建了DDD(钻石继承问题),因为您无法调用:

Wrong wrong;
wrong.Ambig(); 

这是一个模棱两可的函数,因为它被定义了两次:

Wrong::C::Base::Ambig()

并且:

Wrong::D::Base::Ambig()
为了避免这种问题,您应该使用虚拟继承,它会知道引用正确的 Ambig() 函数。
因此,请定义:
class C : public virtual Base

class D : public virtual Base

class Right : public C, public D

19
“错误”完全可以成为“正确”。这取决于情况。在出现(不可怕的)菱形图案的情况下,普通MI和虚拟MI都有它们的用途。只需记住并非所有情况都适用同一种方法。 - Thomas Eding
8
我认为你注意到了错误的事情 —— 用“Wrong”和“Right”类。它们因为一个原因而相同,那就是它们不是问题所在。虽然你正确地为父类C和D使用了虚拟继承,但你基本上概述了它 —— C和D才是“错误”的,需要修复的是它们,而不是从它们派生出来的类。 - Kevin
5
这篇文章需要更明确的结论。说“虚拟继承将知道引用正确的Ambig()函数”是什么意思?它是如何知道的?我不太清楚这如何解决问题。 - Scott Hutchinson
5
我能理解得更清楚了:https://dev59.com/TXVD5IYBdhLWcg3wTZ1m#21607。 - Scott Hutchinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接