虛繼承中對象的構造順序
虛基類的構造
首先虛基類的構造是通過最底層的派生類初始化,並且繼承體系的每個類都可能在某個時刻成爲最低層的派生類
class A{
public:
A(){
}
}
class B:virtual public A{
public:
B(){
}
}
class C:virtual public A{
public:
C(){
}
}
class D:public B,public C{
public:
D(){
}
}
就比如說上面這一個例子,
B b; //b是最底層基類,由b直接構造虛基類a(b先通過a的默認構造函數構造其虛基類a子對象,隨後構造自身)
D d; //在這種情況下,d是最低層基類,由d直接構造基類c(d先通過a的默認構造函數構造其虛基類a子對象,隨後分別通過b和c的默認構造函數構造其基類b和c子對象,最後構造自身
即使a不是d的直接基類,d的構造函數也可以初始化a
需要注意的一點是,如果最低層基類沒有顯示地初始化其虛基類子類對象,則虛基類的默認構造函數將會被調用。如果最底層基類沒有默認構造函數,則代碼會發生錯誤。(在本示例中d非顯示的,通過調用a的默認構造函數構造其虛類子對象a)
構造函數的順序
程序示例
-
首先初始化對象的虛基類子部分
如果一個類含有多個虛基類,則這些虛的子對象按照它們在派生列表中出現的順序從左向右構造
編譯器按照直接基類的聲明順序依次對直接基類進行檢查,以確定其中是否含有虛基類。如果有,則先構造虛基類。(本例在直接基類level1中有虛基類base1,因此先構造base1而不是base2和level12;在構造完base1後,按照從左至右的規則構建虛基類level12子對象,因爲level12子對象的構建需要先構建level12的虛基類子對象base2,所以構造順序是base2、level12;在構造完所有虛基類子對象後,構造非虛類子對象) -
接下來按照直接基類在派生列表中出現的次序依次對其進行初始化
(先構建level11非虛類子對象,level11通過base2的構造函數構造base2子對象後構建其自生,最後toplevel構造自身)
析構函數的調用順序和構造函數相反