1
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 类的一个副本?virtual 关键字在“C 类”中的作用,以便以后影响其派生类(如您所见,我只是想了解虚拟继承的基本工作原理。我试图找出这个问题的答案,但没有得到它是正确的,如果有人知道任何好的链接,即使这会有所帮助。)。换句话说,两者有什么区别

//1)
class C: virtual public B
{ };

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

如果我们不再开 C 级车。在创建对象时,1)和2)之间会有什么特别的区别吗?

4

2 回答 2

1

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

因此,两者C兼有Dvirtual public B两者都准备分享 B

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

于 2013-06-20T03:04:04.660 回答
0

如果我们不进一步学习 C 类。在创建对象时,1)和2)之间会有什么特别的区别吗?

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

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

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

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

于 2013-06-20T03:32:40.710 回答