Come Herb Sutter e Andrei Alexandrescu spiegano nel loro libro C++ Coding Standards (item 34), l'ereditarietà è uno dei rapporti più stretti che C++ consente di utilizzare tra due classi - E 'secondo solo a un rapporto friend
tra le classi.
Secondo lo S.O.L.I.D principles of OO, un progetto di successo dovrebbe mirare allo libero accoppiamento tra classi - questo diminuisce mantenendo le dipendenze al minimo; che a sua volta implica che l'ereditarietà sia uno strumento che dovrebbe essere usato con cautela.
Naturalmente, le dipendenze in genere bisogno di esistere da qualche parte , quindi un compromesso ragionevole può essere ereditato dalle classi senza l'attuazione a tutti (Analogo a cosiddetti interface
s in linguaggi come C# e Java). per esempio.
class IDriveable
{
public:
virtual void GoForward() = 0;
virtual void GoBackward() = 0;
};
class Car : public IDriveable { /* etc. */ };
class Bus : public IDriveable { /* etc. */ };
class Train : public IDriveable { /* etc. */ };
Con questo approccio, se si dispone di elementi di codice reimpiegati tra diversi pilotabile classi, è in genere utilizzato composizione o qualche altra relazione debole per eliminare codice ripetuti.
ad es. forse si vuole riutilizzare il codice per TurnLeft
per un Bus
e un Car
ma non un Train
dove girando a sinistra è illogico, così TurnLeft
potrebbe finire in una classe separata, che è membro-di Bus
e Car
.
- Inoltre, qualsiasi funzionalità che potrebbero aver bisogno di conoscere tutte le classi vagamente legate sarebbe esterno alla gerarchia di classe, solo a conoscenza dell'interfaccia/base, piuttosto che i grattacapi dettagli di implementazione.
Il risultato finale può essere una piccola quantità di codice aggiuntivo per la composizione, ma spesso un progetto meno complesso e in genere uno più facile da gestire. Non ci sono regole durissime per la progettazione di codice come questo dato che dipende interamente dai problemi unici che stai cercando di risolvere.
ci sono altri modi per riutilizzare il codice senza accoppiamento stretto troppo - i modelli consentono di implicitamente definire le interfacce senza classi vuote che contengono puri virtual
funzioni (modelli forniscono una maggiore sicurezza di tipo - che è un buona cosa, ma sono sintatticamente un un po 'più complesso);
E ci sono modi in cui è possibile utilizzare std::function
e lambda per riutilizzare il codice in uno stile più funzionale, anche in questo caso non ci sono solitamente dipendenze strette quando si passa intorno agli oggetti funzione.
fonte
2012-09-26 21:32:58
Grazie per le risposte ragazzi! Li apprezzo davvero. Il motivo per cui ho preso in considerazione l'utilizzo dell'ereditarietà invece della composizione è dovuto anche alla necessità di modificare alcuni comportamenti in A e B. Inoltre non desidero veramente modificare A e B. – user1657624