2013-11-28 3 views
10

Öffentliche Vererbung ist einfach.Was ist der praktische Nutzen der geschützten Vererbung?

A: öffentliches B bedeutet, dass jedes A ein B. ist. In den meisten Programmiersprachen wie vb.net und objective-c ist dies die einzige Art der Vererbung.

Privat Erbe ist auch einfach, aber sinnlos

A: privat B bedeutet, A von B. jedoch umgesetzt wird, das ist sinnlos, weil das bedeutet, A B statt enthalten sollte. Eigentum bedeutet weniger Kopplung ohne Nachteil.

Dann haben wir die Vererbung geschützt.

Kann mir jemand erklären, wofür zum Teufel ist das? Manche sagen, es ist ein "als eine Beziehung". Ich bin darüber noch nicht ganz klar.

Hat jemand einige Beispielfälle, in denen Menschen geschützte Vererbung in gutem Muster (und Gewissen) für den tatsächlichen produktiven Einsatz verwenden?

+0

Ich mag falsch sein, aber ich denke, ich lese in einem der goldenen C++ Bücher (erinnere mich nicht, welche genau), diese "geschützte" Vererbung ist (fast?) Unsinn und (fast?) Nie benutzt. Wie "für zukünftige Verwendung reserviert". Aber, nochmal, ich darf lügen :) –

+0

[diese Antwort] (http://Stackoverflow.com/a/1374362/2513200) von Johannes Schaub hat tatsächlich einen Use Case gefunden. Es wird immer noch als "selten nützlich" bezeichnet. – Hulk

+0

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

Antwort

10

Privat Erbe ist auch einfach, aber sinnlos

A: privat B bedeutet, A von B. jedoch umgesetzt wird, das ist sinnlos, weil das bedeutet, A B statt enthalten sollte. Eigentum bedeutet weniger Kopplung ohne Nachteil.

Dass Sie Gründe für private Vererbung nicht sehen können, bedeutet nicht, dass es sinnlos ist. Es gibt mehrere Fälle, in denen private Vererbung Gründe hat. Auf dem ersten Blick haben Sie Recht, private Vererbung bedeutet: Beziehungen wie Aggregation, und private Vererbung hat eine (etwas) engere Kopplung.

  • Mit private Vererbung Sie typedefs auch erben:

    Gründe für die private Vererbung über aggretations begünstigen könnten einige der folgenden sein. In einigen Fällen (z. B. Merkmalsklassen) ist das private Erben nur die Alternative, um in der Basisklasse Typen von typedefs erneut zu typen. In seltenen Fällen müssen Sie ein Mitglied vor eine "echte" (d. Die einzige Möglichkeit, dies zu erreichen, besteht darin, dieses Mitglied zu einer privaten Basisklasse zu machen, die vor der öffentlichen Basis vererbt wird.

  • Manchmal benötigen Sie Zugriff auf geschützte Mitglieder eines Mitglieds. Wenn Sie die Mitgliedsklasse nicht selbst ändern können, müssen Sie private Vererbung verwenden, um auf sie zuzugreifen.
  • Wenn ein Mitglied keine eigenen Datenelemente besitzt, belegt es noch Speicherplatz. Wenn Sie eine private Basisklasse definieren, wird die leere Basisklassenoptimierung aktiviert und die Größe der Klassenobjekte verringert.
  • für mehr Punkte sogar, siehe James' Kommentaren unten

Diese Gründe offensichtlich technischen Gründen, manche sogar ‚Hacks‘ könnte man sagen. Solche Gründe gibt es jedoch, so dass private Vererbung nicht völlig sinnlos ist. Es ist einfach nicht "reiner OO-Stil" - aber C++ ist auch keine reine OO-Sprache.

Der Grund für geschützte Vererbung sind recht einfach, wenn Sie diejenigen für private Erbschaft verstanden:

Wenn Sie Gründe haben etwas privat und wollen diese Vorteile machen (dh erben, die Mitglied Möchtegern-Ihrer Klasse oder typedefs), die für abgeleitete Klassen zugänglich sind, verwenden Sie die geschützte Vererbung. Offensichtlich sollte das private Erbe kaum genutzt werden, geschütztes Erbe noch mehr.

+1

Es ist erwähnenswert, dass die ursprüngliche Vererbung in Smalltalk eher der privaten als der öffentlichen Vererbung in C++ entspricht. Die Vererbung wurde ursprünglich entwickelt, um die gemeinsame Implementierung, die _not_ shared interface, zu unterstützen. –

+4

Und natürlich haben Sie verpasst, was wahrscheinlich der häufigste Grund für private Vererbung ist: Die Basisklasse bietet eine anpassbare Implementierung, die das Vorlagenmethodenmuster verwendet, und Sie müssen ihre virtuellen Funktionen überschreiben. –

+4

Nicht zu erwähnen, dass die Implementierung einer bestimmten Schnittstelle manchmal ein Implementierungsdetail für Ihre Kunden ist. Die Tatsache, dass ein GUI-Widget ein GUI-Ereignis-Listener ist, betrifft nur das Widget selbst (und wo es sich für die Ereignisse anmeldet). –

4

Die Hauptmotivation für geschützte Vererbung ist Orthogonalität. In allen anderen Kontexten haben Sie drei verschiedene Zugriffskontrollen: privat, geschützt und öffentlich. Warum sollte Vererbung anders sein? In der Praxis könnte man argumentieren, dass es keinen Bedarf gibt oder für den geschützten Zugriff im Allgemeinen zu verwenden. Das kann übertrieben der Fall sein, aber es ist sicher, dass viel weniger geschützt ist als privat oder öffentlich.

Auch private Vererbung ist überhaupt nicht sinnlos, und in der Tat entspricht der ursprünglichen Verwendung der Vererbung. Sobald die Basisklasse, die die Implementierung durchführt, virtuelle Funktionen verwendet, die die abgeleitete Klasse überladen muss, kann Containment nicht verwendet werden.

+1

Ich verwendete einmal eine geschützte virtuelle Basis, um Befehlszeilenargumente für die verschiedenen Durchläufe eines Linkers zu verwalten; Jeder Durchlauf wurde von einem eigenen Typ behandelt, und der Linkertyp wurde von jedem der Durchgangstypen privat abgeleitet. Im Nachhinein bin ich mir nicht sicher, ob das ein gutes Design war oder nur Angeberei. –

Verwandte Themen