Che cos'è l'ereditarietà virtuale?
L'ereditarietà virtuale è un tipo di eredità in cui l'implementazione di una superclasse è incompleta ed è necessaria una sottoclasse per la definizione completa di un oggetto. Questo tipo di ereditarietà può essere utilizzato in combinazione con eredità sia singola che multipla, ma è più comunemente usato in eredità multipla. Qualsiasi classe che eredita da una classe base virtuale diventa una sottoclasse diretta di quella classe base. Una classe di base virtuale può fare affidamento su una sottoclasse per implementare tutti i suoi metodi, ma questo non è un requisito.
C ++ è il linguaggio informatico più comunemente usato per utilizzare l'ereditarietà virtuale. Per dichiarare l'eredità virtuale in C ++, viene utilizzata la parola chiave "virtuale". Sia la superclasse che la sottoclasse devono dichiarare metodi virtuali con la parola chiave "virtuale". Questo dice al compilatore C ++ che la superclasse è incompleta e che deve ottenere informazioni dalla sottoclasse per completarla. L'uso della sottoclasse per completare la superclasse non significa che le sottoclassi si sovrascrivano reciprocamente se hanno la stessa classe base, e invece il compilatore C ++ si occupa di determinare quali pezzi vanno con ogni oggetto.
Poiché è necessaria una classe di base virtuale per l'ereditarietà virtuale, le funzioni globali in C ++ non possono essere dichiarate virtuali. Questo tipo di ereditarietà può essere utilizzato solo quando si aderiscono ai principi di programmazione orientata agli oggetti (OOP). La ragione di ciò è che le funzioni globali non sono associate a una particolare classe, e quindi di solito sono autosufficienti da sole. Senza una superclasse e una sottoclasse l'ereditarietà non può avvenire, quindi le funzioni globali e l'ereditarietà virtuale si escludono a vicenda. Le funzioni globali possono, in teoria, essere utilizzate all'interno di funzioni virtuali, ma il contrario potrebbe non funzionare sempre.
L'ereditarietà virtuale viene utilizzata per risolvere molti problemi di programmazione e uno dei più utili è la risoluzione dell'ambiguità. In eredità multipla, si può avere una classe base A che ha due sottoclassi, B e C, e quindi una classe D che eredita da entrambe le classi B e C. Questo modello è comunemente chiamato "diamante della morte" perché se le classi A, B e C hanno tutte implementazioni dello stesso metodo, non è possibile per la classe D determinare quale implementazione dovrebbe usare. L'eredità virtuale risolve questo problema perché l'implementazione di ogni classe rimane distinta e quindi non ambigua. Questa distinzione è gestita da oggetti interni specializzati chiamati tabelle virtuali (vtables) che tengono traccia di ciascun tipo di oggetto, ma queste tabelle non devono essere esplicitamente manipolate da un programmatore perché sono integrate nel linguaggio.