Zugriff auf Basisklassen und abgeleitete Klassen

Aus Appmethod Topics
Wechseln zu: Navigation, Suche

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 : base-list { <member-list> }

D erbt alle Member dieser Basisklassen. (Neu definierte Basisklassen-Member werden auch geerbt; der Zugriff auf sie kann falls erforderlich durch Änderung des Gültigkeitsbereichs erfolgen.) D kann nur die public- und protected-Member seiner Basisklassen verwenden. Welche Zugriffsattribute erhalten nun aber die geerbten Member, von D aus gesehen? Angenommen, D will einen public-Member aus einer Basisklasse verwenden, ihn für außenstehende Funktionen aber als private-Member schützen. Die Lösung liegt im Gebrauch der Zugriff-Spezifizierer in der Basisliste.

Hinweis: Da eine Basisklasse selbst auch eine abgeleitete Klasse sein kann, ist das Zugriffsattribut 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 die Zugriffsattribute der Basis-Member (von der Basisklasse aus gesehen) nicht, können aber die Zugriffsattribute der Basis-Member (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.

Hinweis: 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-Member der Basisklasse sind public-Member der abgeleiteten Klasse. protected-Member der Basisklasse sind protected-Member der abgeleiteten Klasse. private-Member der Basisklasse bleiben private für die Basisklasse.
  • protected-Basisklasse: Sowohl public- als auch protected-Member der Basisklasse sind protected -Member der abgeleiteten Klasse. private-Member der Basisklasse bleiben private für die Basisklasse.
  • private-Basisklasse: Sowohl public- als auch protected-Member der Basisklasse sind private-Member der abgeleiteten Klasse. private-Member der Basisklasse bleiben private für die Basisklasse.

Beachten Sie, dass private-Member einer Basisklasse von den Member-Funktionen der abgeleiteten Klasse nicht verwendet werden können. Dies gilt allerdings nicht, wenn friend-Deklarationen explizit den Zugriff zulassen. Zum Beispiel:

/* class X is derived from class A */
class X : A {               // default for class is private A
  // …
}
/* class Y is derived (multiple inheritance) from B and C
   B defaults to private B */
class Y : B, public C {     // override default for C
  // …
}
/* struct S is derived from D */
struct S : D {              // default for struct is public D
  // …
}
/* struct T is derived (multiple inheritance) from D and E
   E defaults to public E */
struct T : private D, E {   // override default for D
                            // E is public by default
  // …
}

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. Zum Beispiel:

class B {
   int a;               // private by default
public:
   int b, c;
   int Bfunc(void);
};
class X : private B {   // a, b, c, Bfunc are now private in X
   int d;               // private by default, NOTE: a is not
                        // accessible in X
public:
   B::c;                // c was private, now is public
   int e;
   int Xfunc(void);
};
int Efunc(X& x);        // external to B and 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”-Member von B: b und Bfunc()
  • Die private- und public-Member von X: d, e, und Xfunc()

Xfunc() kann jedoch nicht auf den Member a zugreifen, der für "B private" ist.

Siehe auch