C++-Programmierung/ Objektorientierte Programmierung/ Virtuelle Vererbung

Aus Wikibooks


Nicht virtuelle Vererbung

Eine abgeleitete Klasse kann wiederum als Basisklasse einer Vererbungsbeziehung dienen. Auf diese Weise fungiert eine allgemeine Klasse als Ausgangspunkt für einen ganzen „Vererbungsbaum“. Eine interessante Situation tritt ein, wenn die Baumgestalt verloren geht: Dank der Mehrfachvererbung kann es passieren, dass zwei Klassen durch mehrere Vererbungswege verbunden sind. C++ überlässt dem Programmierer die Entscheidung, ob die zur mehrfach vorhandenen Basisklasse gehörenden Teilobjekte zu einem einzigen verschmolzen werden sollen oder nicht.

Wenn Sie getrennte Teilobjekte haben wollen, müssen Sie nichts weiter tun. Eine fiktive Klasse zum Arbeiten mit Dateien:

class Datei {
  unsigned int position;
  /* ... */
};

class DateiZumLesen     : public Datei { /* ... */ };
class DateiZumSchreiben : public Datei { /* ... */ };

class DateiZumLesenUndSchreiben: public DateiZumLesen, public DateiZumSchreiben { /* ... */ };
Virtuelle Vererbung

Jede Instanz der Klasse DateiZumLesenUndSchreiben hat zwei Teilobjekte der Basisklasse Datei. Das ist hier ein sinnvoller Ansatz, damit Lese- und Schreibzeiger an verschiedenen Positionen stehen können.

Sollen die Teilobjekte verschmolzen werden, kennzeichnen Sie die Vererbung mit dem Schlüsselwort virtual:

// Modifiziertes Beispiel "Person"

class Person {
  string name;
  // ...
};

class Mitarbeiter : public virtual Person { /* ... */ };
class Kunde       : public virtual Person { /* ... */ };

class MitarbeiterUndKunde : public Mitarbeiter, public Kunde { /* ... */ };

Jetzt besitzt eine Instanz der Klasse MitarbeiterUndKunde nur ein Teilobjekt der Basisklasse Person. Insbesondere ist die Membervariable name nur einmal vorhanden und kann konfliktfrei unter diesem Namen angesprochen werden. Beim Anlegen einer Instanz vom Typ MitarbeiterUndKunde wird jetzt allerdings der Konstruktor der Klasse Person nicht mehr indirekt durch die Konstruktoren der Klassen Mitarbeiter und Person aufgerufen, sondern muss explizit aus dem Konstruktor der Klasse MitarbeiterUndKunde aufgerufen werden.