虚拟继承实际上如何工作?

时间:2014-10-22 14:22:10

标签: c++ inheritance virtual-inheritance

我知道钻石问题,但问题是 - 当我谷歌"虚拟继承"结果提到钻石问题。我想知道它是如何工作的,它与正常继承有什么不同。

我知道当一个类(通常)继承自另一个类时,它只包含其所有成员(字段和方法,不考虑访问级别)。其中一些可能会被新成员覆盖或隐藏,但他们仍然存在。继承还定义了层次结构中类之间的某些关系,这些关系会影响转换和多态性。

现在虚拟继承有何不同?例如:

class A
{
    public:
    int a;
    int b;
    void fun(int x)
    {}
    void gun(int x)
    {}
};

class B : public A
{
    public:
    int a;
    int c;
    void fun(int x)
    {}
    void hun(int x)
    {}
};

class C : virtual public A
{
    public:
    int a;
    int c;
    void fun(int x)
    {}
    void hun(int x)
    {}
};

BC之间有什么区别?我的例子没有任何其他差异吗?标准说什么?另外,如果C ++ 03和C ++ 11之间存在差异,请提及它。

1 个答案:

答案 0 :(得分:5)

使用单一级别的继承,行为没有区别。

不同之处在于从多个基类继承时,它们本身具有公共基类:

struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B,C {};

在此示例中,使用虚拟继承,D只包含一个A子对象,其BC个子对象共享;这是“钻石”模式:

    A
   / \
   B C
   \ /
    D

如果没有虚拟继承,它将包含两个A子对象,而不包含“菱形”:

   A A
   | |
   B C
   \ /
    D

有或没有多重继承,如果你有多个继承级别仍然存在差异:虚拟基类必须由派生程度最高的类初始化,而不是由其直接派生类初始化。这是为了避免在多重继承的情况下出现歧义,其中(在上面的示例中)BC都将负责初始化共享A