2012-04-24 87 views
1

如果我有像虚拟继承

class Base1 {}; 

class Base2 {}; 

class Derived : public Base1, public Base2 {}; 

然后构造函数调用对制作的派生类对象顺序

Base1 
Base2 

即他们的顺序出现在

class Derived : public Base1, public Base2 {}; 

但如果我将其更改为 类Derived:public Base1,virtual public Base2 {}; 然后构造函数调用的顺序变为

Base2 
Base1 

我无法理解为什么会是这样?

另一个简单的疑问: 什么是虚拟继承Base1的含义和目的。

+2

11个月你在SO上,你仍然无法正确格式化你的帖子? – BlackBear 2012-04-24 12:53:51

+0

一些帮助http://gotw.ca/gotw/080.htm – DumbCoder 2012-04-24 12:55:29

+0

我假设你有一个错字,因为你声明'Base1'和'Base2',然后使用'Base'和'Base1'。 – Cornstalks 2012-04-24 12:55:48

回答

4

这些只是规则。正在构建的派生类最多,在开始初始化其非虚拟直接基础之前,首先会初始化层次结构中的所有虚拟基类。

的规则来从标准(ISO/IEC 14882:2011),第12.6.2 [class.base.init]/10

一种用于这种方法的理由是,这确保了所有基类在它们的派生类之前被初始化,无论它们是否是虚拟基础。

1

至于虚拟继承。当你有一个衍生类如下

class A {}; 
class B : public virtual A {} ; 
class C : public virtual A {} ; 
class D : B, C { } // this class has only one instance of A! 

又名钻石问题!

3

关于初始化的顺序,Charles已经正确地回答了:那些是规则,首先是声明顺序中的虚拟基础,然后是非虚拟基础中的声明顺序,然后成员变量的顺序是宣言。

虚拟继承的含义是什么?这意味着你的对象派生自那个特定的基础,但是如果在一个层次结构中多于一个的子对象(完整类型的基础)实际上从相同的基类型继承,则只有一个基础子对象存在。您可以将virtual关键字阅读为我愿意与其他对象共享我的base

struct ubase {}; 
struct sbase {}; 
struct A : ubase, virtual sbase {}; // has a sbase subobject, but is willing to share.. 
struct B : ubase, virtual sbase {}; // ... but want to have my own ubase 
struct C : A, B {};     // only one sbase subobject, shared by A and B 
             // ... but two ubase subobjects, A::ubase and B::ubase 

根据第二个问题,你想什么时候使用虚拟继承?无论何时在类型层次结构中,您最终可能会多次从同一个基础继承,并且在您的设计中,所有这些基类的出现都只是一个。一般来说,除少数几种特殊情况外,使用虚拟继承是很少见的。