Se stai usando la classe base come metodo per condividere l'implementazione tra le due (o più) classi derivate e la classe base non rappresenta un'interfaccia, l'ereditarietà pubblica è quasi certamente un errore.
Una possibilità sarebbe di usare l'aggregazione (mettere i dati condivisi in una classe helper e includere un'istanza di quella classe in ogni classe "derivata" che ne ha bisogno).
Un'altra possibilità sarebbe quella di utilizzare l'ereditarietà privata. L'ereditarietà privata viene solitamente descritta come "è implementata in termini di". Laddove l'eredità pubblica deve essere conforme al Principio di sostituzione di Liskov (almeno in un disegno decente), l'ereditarietà privata non comporta tale requisito. Con l'ereditarietà privata, la classe derivata è "consapevole" della sua relazione con la classe base e può utilizzare l'implementazione dalla classe base. Quella relazione è "nascosta" dal mondo esterno, quindi, c'è non una conversione implicita dalla classe derivata alla classe base come avviene con l'ereditarietà pubblica.
class base { };
class D1 : public base { };
class D2 : base { };
int main() {
base *b = new D1; // no problem
base *b2 = new D2; // won't compile
}
Se insisti davvero, puoi convertire un puntatore in derivato in un puntatore in base - ma devi usare un cast (e, cosa interessante, deve essere un cast in stile C, nessuno dei "nuovi" "I cast di C ++ possono farlo correttamente 1 ).
- Per coloro che sono tentati di contestare questo: sì, un
reinterpret_cast
sembrerà fare correttamente il lavoro per alcuni casi - ma (per dare un solo controesempio) se usi l'ereditarietà multipla, verrà convertito solo da derivato uno dei tipi di base correttamente. Tentare di convertire in un altro tipo di base produrrà risultati cattivi.