2013-06-09 16 views
6

sono incappato in questo esempio di codice:virtuale ereditarietà multipla

#include <iostream> 
using namespace std; 

class A { 
    int x; 
public: 
     A() { x = 1; cout << "A"; } 
}; 
class B : virtual public A { 
     int y; 
public: 
     B() { y = 2; cout << "B"; } 
}; 
class C : virtual public B, virtual public A { 
     int z; 
public: 
     C() { z = 3; cout <<"C"; } 
}; 
class D : public A, public B, public C { 
     int t; 
public: 
     D() { t = 4; cout << "D"; } 
}; 
int main() 
{ 
     D d; 
     return 0; 
} 

This code prints ABABCD e non ho idea del perché. Ho pensato che avrebbe stampato A per D : public A, quindi AB per D : public B, quindi ABC per D : public C e quindi D, ma sembra che lo A venga stampato solo due volte. Come funziona?

+0

cosa succede se si cambia 'pubblico A, pubblico B , pubblico C' a 'pubblico virtuale A, pubblico B, pubblico C'? – cmh

+0

@cmh 'ABBCD' ... –

+0

Forse è istruttivo .. – cmh

risposta

8

L'ordine di costruzione delle basi è (ignorando le basi virtuali) da sinistra a destra quando vengono digitate nella relazione di ereditarietà. Una volta aggiunte le basi virtuali, queste vengono inizializzate prima (prima di qualsiasi base non virtuale) in una profondità da sinistra a destra.

Ora questo dovrebbe spiegare l'output.

D: A, B, C

A non ha basi virtuali, B ha un virtuale Una base, in modo che il primo inizializzato: "A". Quindi C ha una base B virtuale, quindi quella successiva viene inizializzata. A questo punto il sotto-oggetto virtuale A è già stato inizializzato, quindi solo il costruttore B viene valutato "AB". A questo punto tutte le basi virtuali sono state costruite e le basi non virtuali sono costruite, prima A, poi B, poi C, quindi il tipo completo D, che produce "ABABCD". Gli oggetti secondari virtuali sono stati tutti costruiti, in modo che non vengano ricostruiti di nuovo.

Alcune cose da tenere a mente. Una base virtuale viene condivisa solo con altri sottooggetti che sono disposti a condividerla (cioè come base virtuale). Non vi è alcun limite a quante volte una base virtuale può essere condivisa all'interno di un oggetto completo (cioè la base virtuale A è condivisa più volte, anche da diversi sottooggetti B)

+0

Grazie mille, questo lo spiega! Grande intuizione –

Problemi correlati