Programmieren in C++
| ||||||||||||||||||||||||
| class A { // Hier steht die Klassenbeschreibung wie gewohnt }; class B : public A |
Wir müssen uns nun noch gedanken über die Zugriffsrechte auf die Member der abgeleiteten Klassen machen. In welcher Form kann auf verschieden deklarierte Member einer Klasse zugegriffen werden - jeweils abhängig von der Art der Ableitung. Folgende Tabelle gibt Aufschluss:
| Ableitung | Zugriffsschutz der Basisklasse |
Zugriffsmöglichkeit der Abgeleiteten Klassen |
| public | public protected private |
public protected kein Zugriff |
| private | public protected private |
private private kein Zugriff |
| protected | public protected private |
protected protected kein Zugriff |
Die Tabelle ist wie folgt zu lesen: Leite ich (wie im obigen Beispiel der Klasse B) public ab, so gilt die erste Zeile der Tabelle. Dort kann ich sehen, dass public-Elemente in der abgeleiteten Klasse ebenfalls public sind, also auch von außerhalb der Klasse verwendet werden. Auf Elemente, die in der Basisklasse private sind, kann auf keinen Fall zugegriffen werden.
Falls vom Programmierer nicht anders angegeben, werden beim Erzeugen von Objekten und deren Zerstörung nach
Ende ihrer Lebensdauer die Konstruktoren und Destruktoren automatisch aufgerufen. Bei Konstruktoren muss dazu jedoch ein
geeigneter (im Normalfall parameterloser) Standart- (Default-)konstruktor in der Klasse vorhanden sein.
In den meisten Fällen möchten wir jedoch, dass die abgeleitete Klasse Werte an einen parametrisierten Konstruktor der
Basisklasse übergibt, um die Elemente der Basisklasse zu füllen. Dies ist besonders dann wichtig, wenn die Basisklasse
private Elemente enthält (auf die wir ja bei Ableitungen laut der obigen Tabelle auf keinen Fall erreicht werden können).
Nun ist es jedoch nicht möglich, einfach vom Konstruktor der abgeleiteten Klasse den der Basisklasse aufzurufen. Aufgrund der
Reihenfolge der Speicherreservierung muss erst der Basisklassenteil inititalisiert werden, bevor die abgeleitete Klasse angelegt wird.
Dazu rufen wir den Konstruktor der Basisklasse auserhalb der Konstruktordefinition innerhalb der Initialisierungsliste des abgeleiteten Konstruktors auf. Dies funktioniert so:
| class A {
} class B : public A
} A::A(int i, double ii) B::B(int i, double ii, char z) : A(i, ii) |
Wir sehen hier die Art des Aufrufs des Basisklassenkonstruktors. Es wird deutlich, dass Parameter, die der Basisklasse mitgegeben werden sollen, bereits Parameter des abgeleiteten Konstruktors sein müssen. Dies wird bei der implementierung gerne vergessen!
Wenn wir in einer abgeleiteten Klasse eine Funktion definieren, die bereits in der Basisklasse vorkommt, so haben wir die Funktion nicht überschrieben, sondern quasi überladen. Rufen wir die Funktion auf der abgeleiteten Klasse auf, so kommt die Basisversion nicht zum Einsatz (entgegen den Regeln bei Konstruktoren). Wir können jedoch unter Angabe des Klassennamens auf die Basisfunktion zurückgreifen. Das sieht dann so aus:
| class A { void f(); } class B : public A void A::f() void B::f()
} |
|
© Gerhard Zapf
|
||||
Letzte Änderung: 11.09.2003 |
||||