2012-04-24 210 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 

根據第二個問題,你想什麼時候使用虛擬繼承?無論何時在類型層次結構中,您最終可能會多次從同一個基礎繼承,並且在您的設計中,所有這些基類的出現都只是一個。一般來說,除少數幾種特殊情況外,使用虛擬繼承是很少見的。