2013-06-29 10 views
7

Consente di guardare il seguente codice:baseclass virtuale chiama costruttore vuoto in 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); 
} 

L'output è:

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

Qualcuno potrebbe spiegarmi perché la classe A il costruttore viene chiamato senza argomenti? In che modo posso "aggiustare" questo comportamento se voglio che la classe B erediti virtualmente da A? (Se l'ereditarietà non è virtuale - l'esempio funziona correttamente)

+0

possibile duplicato di [Ordine di chiamata al costruttore in eredità virtuale] (http://stackoverflow.com/questions/10534228/order-of-constructor-call-in-virtual-inheritance) –

+1

non è questo stato discusso a morte? –

+0

la parola chiave 'virtual' nell'ereditarietà fa sempre chiamare il costruttore il costruttore predefinito della classe base, anche se nella dichiarazione è stato specificato un costruttore non predefinito, in base all'inferenza che la classe base mostrerà più volte nell'albero di ereditarietà e vuoi solo che il costruttore venga chiamato una volta. Si noti inoltre che il costruttore predefinito dall'ereditarietà virtuale viene chiamato prima dall'ereditarietà normale indipendentemente dall'ordine specificato. – Immueggpain

risposta

10

In C++ 03 sarebbe lo stesso.

I costruttori di basi virtuali vengono sempre chiamati dalla classe foglia finale. Se si desidera qualcos'altro rispetto al costruttore predefinito di A durante l'istanziazione di una C, è necessario specificarlo anche nel costruttore della classe C.

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