C++ Kurs

Mehrfach abgeleitete Klassen

Die Themen:

Grundprinzip der Mehrfach-Ableitung

Bisher wurde eine Klasse immer nur von einer Klasse abgeleitet. C++ erlaubt aber auch eine Klasse von mehreren Basisklassen abzuleiten. Die Anzahl der Basisklassen ist nicht begrenzt, jedoch sollte deren Anzahl nicht zu groß werden, da ansonsten leicht der Überblick verloren geht. Unten ist anhand eines kleinen Bildes das Prinzip der mehrfachen Ableitung dargestellt. Die Klasse CMixed vereint alle Eigenschaften/Memberfunktionen der Klassen CBase1 und CBase2 und fügt eventuell eigene hinzu.

Mehrfach Ableitung

Die Ableitung einer Klasse von mehreren Basisklassen erfolgt analog zum Ableiten von einer Basisklasse, nur werden jetzt bei der Definition der abgeleiteten Klasse mehrere Basisklassen, einschließlich deren Zugriffsrechte, aufgeführt. Die einzelnen Basisklassen werden dabei durch Komma voneinander getrennt.

PgmHeader// 1. Basisklasse
class CBase1
{....};
// 2. Basisklasse
class CBase2
{....};

// Neue abgeleitete Klasse
class CMixed: public CBase1, protected CBase2
{....}

Konstruktor und Destruktor

Außer der Klassendefinition muss nun selbstverständlich auch der Konstruktor der abgeleiteten Klasse entsprechend angepasst werden. Er muss jetzt alle Konstruktore seiner Basisklassen aufrufen. Dazu wird, wie bei der einfachen Ableitung, nach der Parameterklammer zunächst ein Doppelpunkt angegeben und danach werden alle Konstruktore der Basisklassen aufgelistet. Einzige Ausnahme: Eine Basisklasse besitzt einen Standard-Konstruktor (parameterloser Konstruktor). In diesem Fall erfolgt der Aufruf automatisch.

PgmHeader// ctor der abgeleiteten Klasse
CMixed::CMixed(P1,P2,...):
   CBase1(a1,a2,...),
   CBase2(b1,b2,...)
{
    ....
}

Die Konstruktore der Basisklassen werden in der Reihenfolge abgearbeitet, in der die Basisklassen bei der Definition der abgeleiteten Klasse aufgeführt sind. D.h. die Reihenfolge der Konstruktoraufrufe bei der Definition des Konstruktors der abgeleiteten Klasse spielt keine Rolle. Im Beispiel unten wird also zuerst der Konstruktor der Klasse CBase1 ausgeführt und danach der Konstruktor der Klasse CBase2. Allerdings sollte bei sauberer Programmierung diese Reihenfolge auch keine Rolle spielen dürfen, da beide Basisklassen voneinander unabhängig sind.

PgmHeader// Definition der abgeleiteten Klasse
class CMixed: public CBase1, protected CBase2
{....}
// Definition des ctors
CMixed::CMixed(P1,P2,...):
   CBase2(a1,a2,...),
   CBase1(b1,b2,...)
{
    ....
}

Und auch für die Abarbeitung der Destruktoren gilt das Gleiche wie bei einfach abgeleiteten Klassen: die Destruktoren werden in umgekehrter Reihenfolge ausgeführt wie die Konstruktore.

Gleichnamige Member in den Basisklassen

Etwas achtgegeben werden muss, wenn die Basisklassen Memberfunktionen mit gleichen Namen enthalten oder sogar die abgeleitete Klasse eine Memberfunktion mit gleichem Namen besitzt wie die Basisklassen. In diesem Fall muss wieder der Klassennamen vor dem Aufruf der Memberfunktion stehen. Dies gilt sogar auch dann, wenn die Memberfunktionen unterschiedliche Parameter besitzen. Wie bereits in einem vorherigen Kaptiel erwähnt, funktioniert das Überladen von Memberfunktionen nur innerhalb einer Klasse und nicht über Klassengrenzen hinweg!

PgmHeader// 1. Basisklasse
class CBase1
{
    ....
    void DoAnything(...);
};
// 2. Basisklasse
class CBase2
{
    ....
    void DoAnything(...);
};
// Neue abgeleitete Klasse
class CMixed: public CBase1, protected CBase2
{
    void AnyMeth(...)
    {
        CBase2::DoAnything();
    }
    ....
}

Ja und das war's auch schon zu mehrfach abgeleiteten Klassen.

BeispielUnd hier geht's zum Beispiel. Die Übung entfällt ausnahmsweise einmal.