2017-04-05 157 views
0

雖然滾過SO,我發現這個問題虛基類和繼承

#include <iostream> 

using namespace std; 

class base 
{ 
    public: 
     base() 
     { 
     cout << "ctor in base class\n"; 
     } 
}; 

class derived1 : public base 
{ 
    public: 
     derived1() 
     { 
     cout <<"ctor in derived class\n"; 
     } 
}; 

int main() 
{ 
    derived1 d1obj; 
    return 0; 
} 

有這樣的問題: - 當創建d1obj,控制首先到達的基類構造函數,然後它去派生類構造函數?或者它是相反的:它首先到達派生類的構造函數,發現它有基類,因此控制權轉到基類的構造函數中?

和aswer包含的部分

當一個類有虛基類是很常見的導致發射出兩個不同的函數體構造 - 一個使用時,這個類是最派生類型,以及一個用於這個類本身就是一個基類的時候。原因是虛擬基類是由派生最多的類構造的,以確保它們共享時只構造一次。因此,構造函數的第一個版本將調用所有基類構造函數,而第二個版本將只調用非虛擬基類的構造函數。

任何人都可以向我解釋這個例子嗎?

Here是鏈接,這個問題

+1

您的示例沒有虛擬基類,因此不能用於解釋問題的粗體斜體部分。這是編譯器如何特別爲虛擬繼承(「鑽石繼承」)構造構造函數的特殊情況,其中類派生自的兩個類具有相同的基類。我從來沒有在我的10多年編程C++中使用它(除了「這裏是一個虛擬繼承的例子」) –

回答

0

「當一個類有虛基類是很常見的導致發射出兩個不同的函數體構造 - 一個使用時,這個類是最派生類型,以及一個用於這個類本身就是一個基類,原因是虛擬基類是由派生類最多的類構造的,以確保它們共享時只構造一次,所以構造函數的第一個版本將調用所有基類構造函數,而第二個版本將只調用非虛擬基類的構造函數。「

在這回答者實際上想談論一種常見於C++的情況,稱爲多重繼承中的可怕鑽石。 要了解剛纔看到的最upvoted回答這個鏈接 In C++, what is a virtual base class?

1

在您的例子是的derived1是負責調用的base默認構造函數的默認構造函數。然而,這僅在必要時derived1是實際的(最派生)對象,如在你的例子

int main() 
{ 
    derived1 d1obj; // Most derived object of type `derived1` 
    // It contains a direct `base` subobject 
    // Constructor of `derived1` must construct `base` subobject as well 
} 

但當derived1使用較大的對象的基子對象

class derived2 : public derived1 
{ 
public: 
    derived2() 
    { 
    cout <<"ctor in derived 2 class\n"; 
    }  
}; 

int main() 
{ 
    derived2 d2obj; // Most derived object of type `derived2` 
    // It contains a direct `derived1` subobject and an indirect `base` subobject 
    // (through `derived1`) 
    // Constructor of `derived2` must directly construct both `derived1` subobject and 
    // `base` subobject 
    // Which means that constructor of `derived1` subobject should not attempt 
    // to construct `base` subobject 
} 

那麼它是derived2的構造函數負責調用默認構造函數derived1和默認構造函數base。在這種情況下,derived1的默認構造函數而不是調用base的構造函數,因爲它將導致base的雙重構造。

爲了滿足所有這些要求,derived1通常會有兩個版本的默認構造函數:在原始示例中調用完整版本,在上面的示例中調用derived2調用「reduced」版本。

或者,derived1的默認構造函數可以用一個隱藏的布爾參數實現,它將告訴它是否調用base的默認構造符。