Um diese Frage zu beantworten, möchte ich die Accessoren der Mitglieder zuerst in meinen eigenen Worten beschreiben. Wenn Sie dies bereits wissen, fahren Sie mit der Überschrift "Weiter:" fort.
Es gibt drei Zugriffsmethoden, die ich kenne: public
, protected
und private
.
Lassen:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
- Alles, was sich bewusst
Base
ist , ist sich auch bewusst, dass es Base
enthält publicMember
.
- Nur die Kinder (und ihre Kinder) wissen, dass
Base
enthält protectedMember
.
- Niemand außer
Base
ist sich dessen bewusst privateMember
.
Mit "ist sich bewusst" meine ich "die Existenz von anerkennen und somit darauf zugreifen können".
Nächster:
Gleiches gilt für die öffentliche, private und geschützte Vererbung. Betrachten wir eine Klasse Base
und eine Klasse Child
, von der geerbt wird Base
.
- Wenn die Vererbung ist
public
, alles, was bekannt ist Base
und Child
auch bekannt ist, von dem Child
erbt Base
.
- Wenn das Erbe ist
protected
, nur Child
, und ihre Kinder, sind sich bewusst , dass sie von erben Base
.
- Wenn die Vererbung ist
private
, ist niemand anderem als Child
der Vererbung bekannt.
SomeBase
wie eine fest codierte Methode ist, um ein anonymes Mitglied des Typs zu komponierenSomeBase
. Dieses hat wie jedes andere Mitglied einen Zugriffsspezifizierer, der dieselbe Kontrolle auf den externen Zugriff ausübt.WICHTIGER HINWEIS: Die Klassen B, C und D enthalten alle die Variablen x, y und z. Es ist nur eine Frage des Zugangs.
Informationen zur Verwendung von geschützter und privater Vererbung finden Sie hier .
quelle
Wenn Sie die Sichtbarkeit der Vererbung einschränken, kann der Code nicht erkennen, dass eine Klasse eine andere Klasse erbt: Implizite Konvertierungen von der abgeleiteten zur Basis funktionieren nicht und
static_cast
von der Basis zur abgeleiteten auch nicht.Nur Mitglieder / Freunde einer Klasse können die private Vererbung sehen, und nur Mitglieder / Freunde und abgeleitete Klassen können die geschützte Vererbung sehen.
öffentliches Erbe
IS-A-Vererbung. Eine Schaltfläche ist ein Fenster, und überall dort, wo ein Fenster benötigt wird, kann auch eine Schaltfläche übergeben werden.
geschützte Vererbung
Geschützt implementiert in Bezug auf. Selten nützlich. Wird verwendet
boost::compressed_pair
, um aus leeren Klassen abzuleiten und Speicher mithilfe der Optimierung für leere Basisklassen zu sparen (Beispiel unten verwendet keine Vorlage, um auf dem neuesten Stand zu bleiben):private Vererbung
Implementiert in Bezug auf. Die Verwendung der Basisklasse dient nur zur Implementierung der abgeleiteten Klasse. Nützlich bei Merkmalen und wenn es auf die Größe ankommt (leere Merkmale, die nur Funktionen enthalten, verwenden die Optimierung der leeren Basisklasse). Oft ist die Eindämmung jedoch die bessere Lösung. Die Größe für Zeichenfolgen ist kritisch, daher wird sie hier häufig verwendet
öffentliches Mitglied
Aggregat
Accessoren
geschütztes Mitglied
Bereitstellung eines erweiterten Zugriffs für abgeleitete Klassen
privates Mitglied
Behalten Sie die Implementierungsdetails bei
Beachten Sie, dass Casts im C-Stil absichtlich das Umwandeln einer abgeleiteten Klasse in eine geschützte oder private Basisklasse auf definierte und sichere Weise und das Umwandeln in die andere Richtung ermöglichen. Dies sollte unter allen Umständen vermieden werden, da dadurch Code von Implementierungsdetails abhängig gemacht werden kann. Bei Bedarf können Sie diese Technik jedoch verwenden.
quelle
Diese drei Schlüsselwörter werden auch in einem völlig anderen Kontext verwendet, um das Sichtbarkeitsvererbungsmodell anzugeben .
In dieser Tabelle werden alle möglichen Kombinationen der Komponentendeklaration und des Vererbungsmodells zusammengefasst, die den resultierenden Zugriff auf die Komponenten darstellen, wenn die Unterklasse vollständig definiert ist.
Die obige Tabelle wird folgendermaßen interpretiert (siehe erste Zeile):
Ein Beispiel:
Die sich ergebende Zugang für Variablen
p
,q
,r
in der Klasse SubSub ist keine .Die sich ergebende Zugang für Variablen
y
,z
in der Klasse Sub ist geschützt und für Variablex
ist keine .Definieren wir nun eine Unterklasse:
Die definierte Klasse mit dem Namen Sub, die eine Unterklasse der Klasse mit dem Namen
Super
oder dieserSub
Klasse ist, wird von derSuper
Klasse abgeleitet. DieSub
Klasse führt weder neue Variablen noch neue Funktionen ein. Bedeutet dies, dass jedes Objekt derSub
Klasse alle Merkmale nach dem erbt?Super
Klasse tatsächlich eine Kopie derSuper
Objekte einer Klasse ist?Nein . Das tut es nicht.
Wenn wir den folgenden Code kompilieren, erhalten wir nur Kompilierungsfehler, die dies aussagen
put
undget
Methoden nicht zugänglich sind. Warum?Wenn wir den Sichtbarkeitsspezifizierer weglassen, geht der Compiler davon aus, dass wir die sogenannte private Vererbung anwenden werden . Dies bedeutet, dass alle öffentlichen Komponenten der Oberklasse zu werden privaten Zugriff umgewandelt werden und auf private Komponenten der Oberklasse überhaupt nicht zugegriffen werden kann. Dies bedeutet folglich, dass Sie letzteres nicht innerhalb der Unterklasse verwenden dürfen.
Wir müssen den Compiler darüber informieren, dass wir die zuvor verwendete Zugriffsrichtlinie beibehalten möchten.
Objekte der
Sub
Klasse können "fast" die gleichen Dinge tun wie ihre älteren Geschwister, die aus derSuper
Klasse erstellt wurden. "Fast", weil die Tatsache, eine Unterklasse zu sein, auch bedeutet, dass die Klasse den Zugriff auf die privaten Komponenten der Oberklasse verloren hat . Wir können keine Mitgliedsfunktion derSub
Klasse schreiben , die die Speichervariable direkt manipulieren könnte.Dies ist eine sehr schwerwiegende Einschränkung. Gibt es eine Problemumgehung?
Ja .
Die dritte Zugriffsebene wird als geschützt bezeichnet . Das Schlüsselwort protected bedeutet, dass sich die damit gekennzeichnete Komponente wie eine öffentliche verhält, wenn sie von einer der Unterklassen verwendet wird, und für den Rest der Welt wie eine private Komponente aussieht . - Dies gilt nur für die öffentlich vererbten Klassen (wie die Super-Klasse in unserem Beispiel) -
Wie Sie im Beispielcode sehen, haben wir eine neue Funktionalität für die
Sub
Klasse und sie macht eine wichtige Sache: Sie greift von der Super-Klasse auf die Speichervariable zu .Es wäre nicht möglich, wenn die Variable als privat deklariert würde. Im Hauptfunktionsbereich bleibt die Variable ohnehin verborgen, wenn Sie also Folgendes schreiben:
Der Compiler informiert Sie darüber, dass es sich um eine handelt
error: 'int Super::storage' is protected
.Schließlich erzeugt das letzte Programm die folgende Ausgabe:
quelle
Dies hängt damit zusammen, wie die öffentlichen Mitglieder der Basisklasse aus der abgeleiteten Klasse verfügbar gemacht werden.
Wie litb hervorhebt, ist die öffentliche Vererbung eine traditionelle Vererbung, die Sie in den meisten Programmiersprachen sehen werden. Das heißt, es modelliert eine "IS-A" -Beziehung. Private Vererbung, etwas, das AFAIK in C ++ eigen ist, ist eine Beziehung, die in Bezug auf die Bedingungen implementiert ist. Das heißt , Sie wollen verwenden die öffentliche Schnittstelle in der abgeleiteten Klasse, aber nicht wollen , den Benutzer von der abgeleiteten Klasse den Zugriff auf diese Schnittstelle haben. Viele argumentieren, dass Sie in diesem Fall die Basisklasse aggregieren sollten, dh anstatt die Basisklasse als private Basis zu haben, in einem Mitglied von abgeleitet machen, um die Funktionalität der Basisklasse wiederzuverwenden.
quelle
Vererbungstyp : Objekt geerbt als :
quelle
1) Öffentliche Vererbung :
ein. Auf private Mitglieder der Basisklasse kann in der abgeleiteten Klasse nicht zugegriffen werden.
b. Geschützte Mitglieder der Basisklasse bleiben in der abgeleiteten Klasse geschützt.
c. Öffentliche Mitglieder der Basisklasse bleiben in der abgeleiteten Klasse öffentlich.
Andere Klassen können also öffentliche Mitglieder der Basisklasse über das abgeleitete Klassenobjekt verwenden.
2) Geschützte Vererbung :
ein. Auf private Mitglieder der Basisklasse kann in der abgeleiteten Klasse nicht zugegriffen werden.
b. Geschützte Mitglieder der Basisklasse bleiben in der abgeleiteten Klasse geschützt.
c. Auch öffentliche Mitglieder der Basisklasse werden geschützte Mitglieder der abgeleiteten Klasse.
Daher können andere Klassen keine öffentlichen Mitglieder der Basisklasse über das abgeleitete Klassenobjekt verwenden. Sie stehen jedoch der Unterklasse Abgeleitet zur Verfügung.
3) Private Vererbung :
ein. Auf private Mitglieder der Basisklasse kann in der abgeleiteten Klasse nicht zugegriffen werden.
b. Geschützte und öffentliche Mitglieder der Basisklasse werden private Mitglieder der abgeleiteten Klasse.
Daher können andere Klassen über das Derived-Klassenobjekt nicht auf Mitglieder der Base-Klasse zugreifen, da sie in der Derived-Klasse privat sind. Daher kann auch die Unterklasse der abgeleiteten Klasse nicht auf sie zugreifen.
quelle
Öffentliche Vererbung modelliert eine IS-A-Beziehung. Mit
jeder
D
ist einB
.Private Vererbung modelliert eine IS-IMPLEMENTED-USING-Beziehung (oder wie auch immer das heißt). Mit
a
D
ist nicht aB
, aber jederD
verwendet esB
in seiner Implementierung. Private Vererbung kann immer durch Verwendung von Containment beseitigt werden:Auch dies
D
kann mitB
, in diesem Fall mit seiner implementiert werdenb_
. Containment ist eine weniger enge Kopplung zwischen Typen als Vererbung, daher sollte es im Allgemeinen bevorzugt werden. Manchmal ist die Verwendung von Containment anstelle von privater Vererbung nicht so bequem wie die private Vererbung. Oft ist das eine lahme Entschuldigung dafür, faul zu sein.Ich glaube nicht, dass jemand weiß, welche
protected
Vererbungsmodelle. Zumindest habe ich noch keine überzeugende Erklärung gesehen.quelle
D
privat abgeleitetD
, kann es virtuelle Funktionen von überschreibenB
. (Wenn es sich beispielsweiseB
um eine Beobachterschnittstelle handelt,D
kann diese implementiert undthis
an Funktionen übergeben werden, für die auch eine Schnittstelle erforderlich ist, ohne dass jeder sieD
als Beobachter verwenden kann.) Außerdem könnenD
Mitglieder von selektivB
in ihrer Schnittstelle verfügbar gemacht werdenusing B::member
. Beides ist syntaktisch unpraktisch zu implementieren, wennB
es sich um ein Mitglied handelt.protected
Vererbung Ich fand nützlich mit einervirtual
Basisklasse undprotected
ctor:struct CommonStuff { CommonStuff(Stuff*) {/* assert !=0 */ } }; struct HandlerMixin1 : protected virtual CommonStuff { protected: HandlerMixin1() : CommonStuff(nullptr) {} /*...*/ }; struct Handler : HandlerMixin1, ... { Handler(Stuff& stuff) : CommonStuff(&stuff) {} };
Wenn Sie öffentlich von einer anderen Klasse erben, weiß jeder, dass Sie erben, und Sie können von jedem über einen Basisklassenzeiger polymorph verwendet werden.
Wenn Sie geschützt erben, können nur Ihre Kinderklassen Sie polymorph verwenden.
Wenn Sie privat erben, können nur Sie selbst übergeordnete Klassenmethoden ausführen.
Dies symbolisiert im Wesentlichen das Wissen, das die übrigen Klassen über Ihre Beziehung zu Ihrer Elternklasse haben
quelle
Auf geschützte Datenelemente können alle Klassen zugreifen, die von Ihrer Klasse erben. Private Datenmitglieder können dies jedoch nicht. Nehmen wir an, wir haben Folgendes:
Innerhalb Ihrer Erweiterung zu dieser Klasse
this.myPrivateMember
funktioniert die Referenzierung nicht. Allerdingsthis.myProtectedMember
wird. Der Wert wird noch gekapselt, so dass , wenn wir eine Instanziierung dieser Klasse haben genanntmyObj
, dannmyObj.myProtectedMember
wird nicht funktionieren, so dass er in der Funktion zu einem privaten Datenelement ähnlich ist.quelle
Basierend auf diesem Beispiel für Java ... Ich denke, eine kleine Tabelle sagt mehr als tausend Worte :)
quelle
Zusammenfassung:
Beim Erben können Sie (in einigen Sprachen) den Schutztyp eines Datenelements in eine bestimmte Richtung ändern, z. B. von geschützt in öffentlich.
quelle
Privat:
Auf die privaten Mitglieder einer Basisklasse können nur Mitglieder dieser Basisklasse zugreifen.
Öffentlichkeit:
Auf die öffentlichen Mitglieder einer Basisklasse können Mitglieder dieser Basisklasse, Mitglieder ihrer abgeleiteten Klasse sowie Mitglieder außerhalb der Basisklasse und der abgeleiteten Klasse zugreifen.
Geschützt:
Auf die geschützten Mitglieder einer Basisklasse können sowohl Mitglieder der Basisklasse als auch Mitglieder ihrer abgeleiteten Klasse zugreifen.
Zusamenfassend:
privat : Basis
geschützt : Basis + abgeleitet
public : base + abgeleitet + jedes andere Mitglied
quelle
Ich fand eine einfache Antwort und dachte deshalb daran, sie auch für meine zukünftige Referenz zu veröffentlichen.
Es ist von den Links http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
quelle
Es ist im Wesentlichen der Zugriffsschutz der Öffentlichkeit und der geschützten Mitglieder der Basisklasse in der abgeleiteten Klasse. Bei der öffentlichen Vererbung kann die abgeleitete Klasse öffentliche und geschützte Mitglieder der Basis sehen. Mit privater Vererbung kann es nicht. Mit protected können die abgeleitete Klasse und alle daraus abgeleiteten Klassen sie sehen.
quelle