2013-01-06 11 views
3
#include<iostream.h> 
class A{ 
    public: 
     int i; 
      A(int j=3):i(j){} 
}; 
class B:virtual public A{ 
    public: 
     B(int j=2):A(j){} 
}; 
class C:virtual public A{ 
    public: 
     C(int j=1):A(j){} 
}; 
class D:public B, public C {  
    public: 
     D(int j=0):A(j), B(j+1), C(j+2){} 
}; 

int main() 
{ 
    D d; 
    cout<<d.i; 
    return 0; 
} 

我無法理解最終輸出是如何爲零的。每次j以默認方式初始化爲某個固定值時,如何將類D的構造函數中初始化的值傳遞給類A?這個初始化列表是如何使用虛擬類實現的?

+0

請告訴我們你在使用什麼*語言*,將它添加爲標籤。 – deceze

+0

它在C++ @petrotta –

回答

2

由於A是一個虛基類,應該只有一次構建,所以它是不可能的用不同的構造函數參數創建它,C++編譯器必須選擇一種創建基類的方法。

顯而易見的問題是:使用哪一個?

而規則是:最直接繼承A的派生類中指定的規則。初始化順序很簡單:首先A(用D構造函數初始化列表中的參數值),然後B(它是D的第一個祖先;它使用之前創建的A的實例),然後C(並且它共享相同的A實例),最後D(並且它也與B和C共享相同的A對象)。

+0

但我們看到在A中int j = 3的值是固定的,所以即使0通過D傳遞給A,也不會將此值再次覆蓋爲3,並最終將我初始化爲3。我被j intiallise爲0,而不是像A的構造函數中提到的那樣使用j = 3。 –

+0

3是默認值。只有當其他人沒有通過時,它才被用作參數。在你的情況下,0顯式傳遞,3被忽略。 – Ellioh

2

與虛擬基礎繼承的規則是:

「的層次來最派生類必須建立一個虛擬的基地」

在你的情況,從最派生類D你明確地稱爲構造函數A通過傳遞參數0因此,它將i設置爲0。正如規則中所提到的,虛擬基類只是通過大多數派生類構造的,其他構造函數通過中間層次調用沒有效果,因爲它只構造一次。

調用的順序是:

A(int) 
B(int) 
C(int) 

良好閱讀:
Why virtual base class constructors called first?

相關問題