考虑其示出了多级继承以下示例代码:
情况1:在此,类derived1
从类派生的base
通过虚拟继承和类derived2
从类派生derived1
直接。
class base
{
};
class derived1 : virtual public base
{
};
class derived2 : public derived1
{
};
案例2:与案例1除了没有虚继承参与
class base
{
};
class derived1 : public base // no virtual inheritance
{
};
class derived2 : public derived1
{
};
假设我创建类的对象derived2
在这两种情况下。
如何案例1和案例2中的对象的差异是子对象的遏制与derived2
?
难道案例1有超过案例2意义?
PS:我是一个虚基类的多重继承过程中的重要性清晰。
如果没有在继承层次的基类的多个实例有(至少)两个其他问题一起考虑virtual
基类。
首先,虚拟基类总是由正在建设和非虚基类之前最派生类初始化。 当中间的类将参数传递给虚拟基类构造函数在其成员初始化列表这是最明显的。 这些初始化将被忽略。 它也可以使施工基类的顺序不同。
其次,它不能够执行static_cast
从虚拟基类到从它继承的类。
有使用虚拟继承时,存储更多的信息。 这是为了让动态类型转换,妥善解决派生类中的钻石局面的情况下。 您的代码没有钻石的情况,所以不使用的信息。
如果数据成员添加到基类的附加信息,可取得明显:
class base {
protected:
int i;
};
如果现在打印在每一个你的每一个两例派生类的大小,你会从一个案件到另一个观察其大小的差异。
编辑:查尔斯·贝利使优秀的点大约使用虚拟继承语义差异。 他的第一点是特别有意思的,应该给予更多的考虑。 他的观点基本上是derived2
有一个隐菱形布局。 也就是说,假设derived1
实际上从继承base
:
class base {};
class derived1 : virtual public base {};
然后,有这三个版本之间没有区别derived2
,他们都表现得像第一个:
class derived2 : virtual public base, public derived1 {};
class derived2 : public derived1, virtual public base {};
class derived2 : public derived1 {}
这意味着,还有就是当你从像类派生创建一个隐含的钻石derived1
(也就是,一个已经使用虚拟继承)。
base
| \
| \.(virtual)
| / \
| /___\
| |
| derived1
| /
| /
|./
/ \
/___\
|
derived2
为了进一步说明这一点,这是允许的时derived1
使用虚拟继承:
class derived2 : public derived1 {
public:
derived2 () : base() {}
};
但是,如果这是不允许的derived1
不使用虚拟继承。
虚拟的传承在你的情况下,没有任何意义。
它仅用于缩进DIAMON的传承,如:
B: A
C: A
D: B, C
在从A在这两种情况下,这种情况下的传承应该是虚拟的。
虚拟继承变得显著只有当类包含作为基类不止一次。 事实上,符virtual
这里的意思是“只包括一次”。
当你没有多重继承,你不能指定同一类数次(循环继承是一个明显的语法错误)。 然后,它涉及到如何好聪明是你的编译器优化。 如果编译器是完美的,那么有没有什么区别。 实事求是地讲,你拿起编译器将添加一些有关于多重继承类的风险。 语言的较少一些功能使用,更大的风险,即编译器会感到困惑。 编译器通常是一个高品质的节目,但仍这只是一个程序。
文章来源: Does “virtual base class in the case of multilevel inheritance” have significance