2013-06-29 13 views
7

Spójrzmy na poniższy kod:wirtualnej klasy bazowej wywołuje pusty konstruktor w C++ (C++ 11)

class A{ 
protected: 
    int _val; 
public: 
    A(){printf("calling A empty constructor\n");} 
    A(int val):_val(val){printf("calling A constructor (%d)\n", val);} 
}; 

class B: virtual public A{ 
public: 
    B(){printf("calling B empty constructor\n");} 
    B(int val):A(val){printf("calling B constructor (%d)\n", val);} 
}; 

class C: public B{ 
public: 
    C(){printf("calling C empty constructor\n");} 
    C(int val):B(val){printf("calling C constructor (%d)\n", val);} 
}; 

int main(void) { 
    C test(2); 
} 

wyjście jest:

calling A empty constructor 
calling B constructor (2) 
calling C constructor (2) 

Może ktoś mi wyjaśnić, dlaczego klasa konstruktor jest wywoływany bez żadnych argumentów? Dodatkowo, w jaki sposób mogę "naprawić" to zachowanie, jeśli chcę, aby klasa B dziedziczyła wirtualnie z A? (Jeśli dziedziczenie nie jest wirtualne - próbka działa poprawnie)

+0

możliwe duplikat [Orderu wywołania konstruktora w wirtualnym dziedziczenia] (http://stackoverflow.com/questions/10534228/order-of-constructor-call-in-virtual-inheritance) –

+1

nie ma to zostały omówione na śmierć? –

+0

Słowo kluczowe "wirtualny" w dziedziczeniu zawsze powoduje, że konstruktor wywołuje domyślny konstruktor klasy podstawowej, nawet jeśli w deklaracji określono inny niż domyślny konstruktor, na podstawie wniosku, że klasa bazowa będzie pokazywana wiele razy w drzewie dziedziczenia i chcesz, aby tylko jeden konstruktor był wywoływany. Zauważ również, że domyślny konstruktor z dziedziczenia wirtualnego jest wywoływany przed tym z dziedziczenia normalnego, niezależnie od kolejności, którą mógłbyś określić. – Immueggpain

Odpowiedz

10

W wersji C++ 03 byłby taki sam.

Wirtualne konstruktory bazowe są zawsze wywoływane z końcowej klasy liści. Jeśli chcesz coś innego niż domyślny konstruktor dla A podczas tworzenia wystąpienia C, musisz to również określić w konstruktorze klasy C.

C(int val): A(val), B(val) {printf("calling C constructor (%d)\n", val);} 
Powiązane problemy