虚拟继承如何工作

时间:2013-06-20 02:57:32

标签: c++ virtual-inheritance

class B
{
public:
    B(char c = 'a') : m_c(c) {}

public:
    fun();

private:
    char m_c;
};

class C: virtual public B
{ };

class D: virtual public B
{ };

class E
    : public C
    , public D
{ };

我只是想知道“虚拟”关键字如何帮助E类只有一个B类副本?虚拟关键字在“C类”中做了什么,以便以后影响其派生类(您可以理解我只是想了解虚拟继承的基本工作。我试图找出这个问题的答案,但没有得到如果有人知道任何好的联系,即使可以提供帮助也是如此。)换句话说,

之间有什么区别
//1)
class C: virtual public B
{ };

//2)
class C: public B
{ };

如果我们不再进一步驾驶C级。在创建其对象时,1)和2)之间是否存在任何特殊差异。

2 个答案:

答案 0 :(得分:1)

使用关键字virtual读取“我将分享”。没有读“我不会分享”

因此CD都有virtual public B,两者都准备分享B

在最后一个例子class C: public B中,C类不会共享 - 即拥有自己的副本。

答案 1 :(得分:0)

  

如果我们不再进一步研究C级。在创建其对象时,1)和2)之间是否存在任何特殊差异。

  • 虚拟基础的构建发生在其他基类之前,即使这些其他基类在类定义的前面列出,并且之后发生了破坏。这不会影响您的“C”类,但如果您添加了另一个基础,则可以。

  • 具有虚拟基类的版本的默认构造函数永远不会“微不足道”,具有各种含义。例如,即使构造函数尚未运行(主要与动态加载的对象相关),也可以安全地获取普通构造对象的数据成员的地址,在联合等中使用时会有一些差异。

标准没有规定实施细节,但是具有虚拟基础的类可能会略大,和/或构造和/或破坏可能稍微慢一些。

对于更长的派生链还有一些其他的怪癖,例如:如果中间类的构造函数的初始化列表指定了虚拟基础构造的参数,那么它们将被忽略以支持更多派生类的构造函数,并且可以省略构造即使虚拟基础中没有默认构造函数,也要从中间类调用。