Zugriff auf Basisklassen und abgeleitete Klassen
Nach oben zu Gültigkeitsbereich von Elementen - Index
Bei der Deklaration einer abgeleiteten Klasse D werden die Basisklassen B1, B2, ... durch Komma getrennt in einer Basisliste aufgeführt:
class-key D : Basisliste { <Elementliste> }
D erbt alle Elemente dieser Basisklassen. (Neu definierte Basisklassen-Elemente werden auch geerbt; der Zugriff auf sie kann falls erforderlich durch Änderung des Gültigkeitsbereichs erfolgen.) D kann nur die public- und protected-Elemente seiner Basisklassen benutzen. Welche Zugriffsattribute erhalten nun aber die geerbten Elemente, von D aus gesehen? Angenommen, D will ein public-Element aus einer Basisklasse benutzen, es für außenstehende Funktionen aber als private-Element schützen. Die Lösung liegt im Gebrauch der Zugriff-Spezifizierer in der Basisliste.
Anmerkung: Da eine Basisklasse selbst auch eine abgeleitete Klasse sein kann, ist das Zugrifffsattribut rekursiv: Sie gehen also zurück bis zur elementarsten Basisklasse, jener, die selbst nicht erbt.
Bei der Deklaration von D können Sie die Zugriff-Spezifizierer public, protected oder private in die Basisliste vor den Klassen einsetzen:
class D : public B1, private B2, ... { . . . }
Diese Modifizierer ändern nicht die Zugriffsattribute der Basiselemente (von der Basisklasse aus gesehen), können aber die Zugriffsattribute der Basiselemente (von der abgeleiteten Klasse aus gesehen) ändern.
Ist D eine class-Deklaration, wird standardmäßig der Zugriff-Spezifizierer private verwendet. Dagegen ist public der Standard, wenn D eine struct-Deklaration ist.
Anmerkung: Varianten können keine Basisklassen enthalten und dürfen nicht als Basisklassen verwendet werden.
Eine abgeleitete Klasse erbt ihre Zugriffsattribute von einer Basisklasse wie folgt:
- public-Basisklasse: public-Elemente der Basisklasse sind public-Elemente der abgeleiteten Klasse. protected-Elemente der Basisklasse sind protected-Elemente der abgeleiteten Klasse. private-Elemente der Basisklasse bleiben private für die Basisklasse.
- protected-Basisklasse: Sowohl public als auch protected-Elemente der Basisklasse sind protected-Elemente der abgeleiteten Klasse. private-Elemente der Basisklasse bleiben private für die Basisklasse.
- private-Basisklasse: Sowohl public als auch protected-Elemente der Basisklasse werden private-Elemente der abgeleiteten Klasse. private-Elemente der Basisklasse bleiben private-Elemente der Basisklasse.
Beachten Sie, dass private-Elemente einer Basisklasse von den Elementfunktionen der abgeleiteten Klasse nicht benutzt werden können. Dies gilt allerdings nicht, wenn friend-Deklarationen explizit einen Zugriff erlauben. Zum Beispiel:
/* class X ist abgeleitet von class A */ class X : A { // private A ist der Default für class . . . } /* class Y ist durch Mehrfachvererbung von B und C abgeleitet B ist standardmäßig private B */ class Y : B, public C { // überschreibt den Default für C . . . } /* struct S ist von D abgeleitet */ struct S : D { // public D ist der Default für struct . . . } /* struct T ist durch Mehrfachvererbung von D und E abgeleitet E ist per Default public E */ struct T : private D, E { // überschreibt den Default für D // E ist per Vorgabe public . . . }
Die Wirkung von Zugriff-Spezifizierern in der Basisliste kann durch Verwendung von qualifizierten Namen in der public- oder protected-Deklaration der abgeleiteten Klasse noch weiter geändert werden. Ein Beispiel:
class B { int a; // per Vorgabe private public: int b, c; int Bfunc(void); }; class X : private B { // a, b, c und Bfunc sind nun private in X int d; // per Vorgabe private, HINWEIS: auf a kann // in X nicht zugegriffen werden public: B::c; // c war private; jetzt public int e; int Xfunc(void); }; int Efunc(X& x); // extern zu B und X
Die Funktion Efunc() kann nur die public-Namen c, e und Xfunc() verwenden.
Die Funktion Xfunc ist ein Element der Klasse X, die von private B abgeleitet ist. Xfunc hat demnach Zugriff auf
- c, dessen Zugriffsattribut in public geändert wurde
- Die “private-für-X”-Elemente von B: b und Bfunc()
- Die private- und public-Elemente von X: d, e, und Xfunc()
Xfunc() kann jedoch nicht auf das Element a zugreifen, das "für B private" ist.