2013-11-28 16 views
10

L'eredità pubblica è facile.Qual è l'uso pratico dell'eredità protetta?

A: pubblico B significa ogni A è un B. Nella maggior parte dei linguaggi di programmazione, come vb.net e oggettivo-c, questo è l'unico tipo di ereditarietà.

eredità privata è anche facile, ma inutile

A: B privato significa che A è implementato da B. Tuttavia, questo è inutile, perché significa che A dovrebbe contenere B invece. Proprietà significa meno accoppiamento senza svantaggi.

Quindi abbiamo protetto l'ereditarietà.

Qualcuno può spiegarmi a cosa diavolo serve? Alcuni dicono che è un "come una relazione". Non sono ancora molto chiaro su questo.

Qualcuno ha alcuni esempi di casi in cui le persone utilizzano l'eredità protetta secondo un buon modello (e coscienza) per un effettivo utilizzo produttivo?

+0

Potrei sbagliarmi, ma penso di aver letto in uno dei libri d'oro C++ (non ricordo quale sia esattamente), che l'eredità "protetta" è (quasi?) Un'assurdità e (quasi?) Mai usata. Come "riservato per uso futuro". Ma, ancora una volta, posso mentire :) –

+0

[questa risposta] (http://stackoverflow.com/a/1374362/2513200) di Johannes Schaub ha effettivamente trovato un caso d'uso. Lo chiama ancora "Raramente utile". – Hulk

+0

Oppure prova [questo] (http://stackoverflow.com/questions/374399/why-do-we-actually-need-private-or-protected-inheritance-in-c/374423#374423) – neutrino

risposta

10

eredità privata è anche facile, ma inutile

A: B privato significa che A è implementato da B. Tuttavia, questo è inutile, perché significa che A dovrebbe contenere B invece. Proprietà significa meno accoppiamento senza svantaggi.

Che potresti non vedere le ragioni dell'ereditarietà privata non significa che sia inutile. Ci sono diversi casi in cui l'ereditarietà privata ha le sue ragioni. Hai ragione in questo a prima vista, l'ereditarietà privata significa che ha relazioni come l'aggregazione e che l'ereditarietà privata ha un accoppiamento (leggermente) più stretto.

Motivi per favorire l'ereditarietà privata oltre aggretations potrebbero essere alcuni dei seguenti:

  • Con l'ereditarietà privata si eredita typedef pure. In alcuni casi (ad esempio classi di tratti) ereditare privatamente è solo l'alternativa a ri-typedef di typedef nella classe base.
  • In casi rari è necessario inizializzare un membro prima di una classe di base "reale" (cioè pubblica). L'unico modo per ottenerlo è rendere quel membro una classe base privata ereditata dalla base pubblica.
  • Alcune volte è necessario accedere ai membri protetti di un membro. Se non è possibile modificare la classe membro stessa, è necessario utilizzare l'ereditarietà privata per accedervi.
  • Se un membro non ha membri dati propri, occupa ancora spazio. Rendendolo una classe base privata abilita l'ottimizzazione della classe base vuota, diminuendo la dimensione degli oggetti della classe.
  • anche per più punti, vedere i commenti di James' sotto

Queste ragioni sono ovviamente ragioni tecniche, alcuni potrebbero anche dire 'hack'. Tuttavia, tali ragioni esistono, quindi l'ereditarietà privata non è completamente inutile. Non è solo "puro stile OO", ma anche il C++ non è un puro linguaggio OO.

La ragione di eredità protetta sono abbastanza semplice, una volta che hai capito quelli per l'ereditarietà privata:

Se avete motivi per ereditare qualcosa privatamente e vuole fare quei benefici (vale a dire che gli aspiranti membro della vostra class o typedefs) accessibile alle classi derivate, usa l'ereditarietà protetta. Ovviamente, l'ereditarietà privata dovrebbe essere usata a malapena, e l'ereditarietà protetta ancora di più.

+1

Vale la pena sottolineare che l'ereditarietà originale, per esempio Smalltalk, corrisponde più all'eredità privata che al pubblico in C++. L'ereditarietà è stata originariamente progettata per supportare l'implementazione condivisa, _non l'interfaccia condivisa. –

+4

E ovviamente, ti sei perso quello che è probabilmente il motivo più comune dell'ereditarietà privata: la classe base fornisce un'implementazione personalizzabile, utilizzando lo schema del metodo del modello, e devi sovrascrivere le sue funzioni virtuali. –

+4

Senza contare che a volte il fatto di implementare un'interfaccia particolare è un dettaglio di implementazione per i client. Il fatto che un widget GUI sia un listener di eventi della GUI riguarda solo il widget stesso (e dove si inserisce per gli eventi). –

4

La motivazione principale per l'ereditarietà protetta è l'ortogonalità. in tutti gli altri contesti, hai tre diversi controlli di accesso: privato, protetto e pubblico. Perché l'eredità dovrebbe essere diversa? In pratica, si potrebbe sostenere che non è necessario o utilizzare per l'accesso protetto in generale. Questo potrebbe esagerare nel caso , ma è certo che molto meno è protetto rispetto a privato o pubblico.

Inoltre, l'ereditarietà privata non è affatto inutile, e infatti, corrisponde all'utilizzo originale dell'ereditarietà. Non appena la classe base esegue l'implementazione utilizza funzioni virtuali che la classe derivata deve sovraccaricare, il contenimento non può essere utilizzato.

+1

Una volta ho usato una base virtuale protetta per gestire gli argomenti della riga di comando per i vari passaggi di un linker; ogni pass è stato gestito da un proprio tipo e il tipo di linker è stato derivato in modo privato da ciascuno dei tipi di pass. Con il senno di poi non sono sicuro se questo fosse un buon progetto o semplicemente mettersi in mostra. –

Problemi correlati