2010-12-28 11 views
18

Vedo da this entry che l'ereditarietà virtuale aggiunge sizeof (puntatore) all'impronta di memoria di un oggetto. Oltre a questo, ci sono degli svantaggi per me semplicemente utilizzando l'ereditarietà virtuale per impostazione predefinita e l'ereditarietà convenzionale solo quando necessario? Sembra che porterebbe a un design di classe più a prova di futuro, ma forse mi manca qualche trappola.In C++, dovrei quasi sempre utilizzare l'ereditarietà virtuale?

+2

L'ordine di inizializzazione delle classi base diventa non ovvio per la maggior parte delle persone. Quindi aumentano i costi di manutenzione. –

+0

L'ereditarietà virtuale aggiunge un puntatore interno solo su alcune implementazioni. Itanium ABI non usa puntatori interni, solo vptr. – curiousguy

risposta

20

Gli svantaggi sono che

  1. Tutte le classi dovranno inizializzare tutte le sue basi virtuali tutto il tempo (ad esempio se A è base virtuale di B, e C deriva da B, inoltre ha inizializzare A stesso).
  2. Devi usare più costoso dynamic_cast ovunque tu usi un static_cast (potrebbe o meno il problema, a seconda del tuo sistema e se il tuo design lo richiede).

Punto 1 da solo non ne vale la pena, dal momento che non è possibile nascondere le basi virtuali. C'è quasi sempre un modo migliore.

+0

Oh dio (1) è orribile. Grazie! Potresti essere più esplicito riguardo (2)? Vuoi dire che il compilatore genera un errore se provo a usare static_cast (my_virtual_base_instance)? – SuperElectric

+1

@SuperElectric: perché (1) è orribile? Sarebbe meglio se un suboject di base non fosse inizializzato? ;) – Yttrill

+3

Commenti come "non ne vale la pena" mostrano un completo fallimento nel comprendere lo scopo delle basi virtuali: l'ereditarietà virtuale deve * sempre * essere usata quando si sottoclassa un'astrazione. Non c'è soluzione alternativa o altra possibilità, se non si riesce a utilizzarlo non è possibile utilizzare più sottoclassi di astrazioni senza tornare indietro e correggere l'errore di progettazione, interrompendo così l'incapsulamento. – Yttrill

11

Nella mia esperienza, l'ereditarietà virtuale (al contrario dei metodi virtuali ) non è quasi mai necessaria. In C++ è usato per indirizzare lo "diamond inheritance problem", che se si evita l'ereditarietà multipla non può realmente accadere.

Sono sicuro che non ho mai riscontrato un'ereditarietà virtuale al di fuori dei libri C++, che include sia il codice che scrivo sia i milioni di sistemi di linea che mantengo.

+0

La libreria di flussi di I/O standard C++ utilizza l'ereditarietà virtuale. Ma sì, a parte questo è in genere piuttosto raro. –

+0

Greg: +1 ottima generalizzazione sull'intero pasticcio dell'ereditarietà virtuale. –

+1

Hmm ... so già a cosa serve (sto pensando di usarlo), e capisco che è raro (codice in C++), ma la domanda posta era "quali sono gli svantaggi dell'ereditarietà virtuale". – SuperElectric

Problemi correlati