L'ereditarietà virtuale è rilevante solo se le classi ereditano da Foo
.Se io definisco il seguente:
class B {};
class L : virtual public B {};
class R : virtual public B {};
class D : public L, public R {};
Poi l'oggetto finale conterrà una sola copia del B
, condivisa da entrambe L
e R
. Senza lo virtual
, un oggetto di tipo D
conterrà due copie di B
, uno in L
e uno in R
.
C'è qualche argomento che tutte le eredità dovrebbe essere virtuale (perché nei casi in cui si fa la differenza, questo è ciò che si desidera la maggior parte del del tempo). In pratica, tuttavia, l'ereditarietà virtuale è costosa e, nella maggior parte dei casi, non è necessario : in un sistema ben progettato, la maggior parte dell'eredità sarà semplicemente di una classe concreta che eredita da una o più interfacce " "; una classe così concreta di solito non è progettata per essere derivata da se stessa, quindi non ci sono problemi. Ma ci sono importanti eccezioni: se, ad esempio, si definisce un'interfaccia, e poi estensioni per l'interfaccia, le estensioni devono ereditare praticamente dall'interfaccia di base, dal momento che una concreta attuazione potrebbe voler implementare diverse estensioni. O se stai progettando mixin, dove le classi implementano solo parte dell'interfaccia e la classe finale eredita da diverse di queste classi (una per parte dell'interfaccia ). Alla fine, il criterio da quanto alla possibilità di ereditare praticamente o no, non è troppo difficile:
se l'eredità non è pubblica, probabilmente non dovrebbe essere virtuale (non ho mai visto un'eccezione), altrimenti
se la classe non è progettato per essere una classe base, non c'è bisogno di eredità virtuale, altrimenti
l'eredità dovrebbe essere virtuale.
Ci sono alcune eccezioni, ma le regole di cui sopra sbagliare sul lato della sicurezza; di solito è "corretto" ereditare praticamente anche nei casi in cui l'ereditarietà virtuale non è necessaria.
Un punto finale: una base virtuale deve sempre essere inizializzato dalla classe più derivata, non classe che eredita direttamente (e dichiara che l'eredità è virtuale). In pratica, tuttavia, questo è un non-problema. Se si considerano i casi in cui l'ereditarietà virtuale ha senso, è sempre che eredita da un'interfaccia, che non conterrà dati e quindi avrà (solo) un costruttore predefinito. Se ti ritrovi a ereditando virtualmente da classi con costruttori che accettano argomenti , è ora di fare alcune domande serie sul design.
fonte
2011-11-16 09:35:06
Non ho intenzione di rispondere perché l'argomento non merita davvero un trattamento così superficiale: ma senza 'virtuale' ogni classe che eredita da' Bar' avrà la propria copia di 'Bar', con' virtuale' la classe più derivata avrà solo una copia di 'Bar'. –
Prova: [questa ricerca] (http://stackoverflow.com/search?q = virtuale + ereditarietà +% 5Bc% 2B% 2B% 5D) –
possibile duplicato di [In classe base virtuale C++?] (http://stackoverflow.com/questions/21558/in-c-virtual-base-class) –