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)之间是否存在任何特殊差异。
答案 0 :(得分:1)
使用关键字virtual
读取“我将分享”。没有读“我不会分享”
因此C
和D
都有virtual public B
,两者都准备分享B
在最后一个例子class C: public B
中,C类不会共享 - 即拥有自己的副本。
答案 1 :(得分:0)
如果我们不再进一步研究C级。在创建其对象时,1)和2)之间是否存在任何特殊差异。
虚拟基础的构建发生在其他基类之前,即使这些其他基类在类定义的前面列出,并且之后发生了破坏。这不会影响您的“C”类,但如果您添加了另一个基础,则可以。
具有虚拟基类的版本的默认构造函数永远不会“微不足道”,具有各种含义。例如,即使构造函数尚未运行(主要与动态加载的对象相关),也可以安全地获取普通构造对象的数据成员的地址,在联合等中使用时会有一些差异。
标准没有规定实施细节,但是具有虚拟基础的类可能会略大,和/或构造和/或破坏可能稍微慢一些。
对于更长的派生链还有一些其他的怪癖,例如:如果中间类的构造函数的初始化列表指定了虚拟基础构造的参数,那么它们将被忽略以支持更多派生类的构造函数,并且可以省略构造即使虚拟基础中没有默认构造函数,也要从中间类调用。