C++ Tutorial

Virtuelle Basisklassen

Probleme bei Mehrfach-Ableitung

Um den Einsatz von virtuellen Basisklassen zu veranschaulichen, sehen wir uns die folgende Klassenhierarchie an.

Oberste Basisklasse ist die Klasse WinBase. Davon abgeleitet werden die beiden Klassen Frame und Menu. Und aus diesen beiden Klassen wird eine neue Klasse Window gebildet. Da sowohl Frame als auch Menu von WinBase abgeleitet sind, erben diese beiden Klassen die Eigenschaften von WinBase. Wird aus Frame und Menu eine neue Klasse gebildet, enthält die neue Klasse die Eigenschaften von WinBase in zweifacher Ausführung, einmal von Frame und einmal von Menu.

Virtuelle Basisklassen

Wird eine Klasse von mehreren Basisklassen abgeleitet, die wiederum von einer gemeinsamen Basisklasse abgeleitet sind, kann durch virtuelles Ableiten von der Basisklasse vermieden werden, dass die Eigenschaften der obersten Basisklasse mehrfach weitervererbt werden. In unserem Beispiel sind die Klassen Frame und Menu virtuell von WinBase abzuleiten.

Um eine Klasse virtuell abzuleiten, wird vor oder nach dem Zugriffsrecht der Ableitung das Schlüsselwort virtual gestellt. Dabei ist zu beachten, dass nur die gemeinsame Basisklasse virtuell abgeleitet wird, im Beispiel die Klasse WinBase.

1: // Oberste Basisklasse
2: class WinBase
3: {...};
4: // 1. virtuell abgeleitete Klasse
5: class Frame: virtual public WinBase
6: {...};
7: // 2. virtuell abgeleitete Klasse
8: class Menu: virtual public WinBase
9: {...};
10: // Endgültige Klasse
11: class Window: public Frame, public Menu
12: {...};

Auf eine Besonderheit beim virtuellen Ableiten muss hingewiesen werden. Benötigt der Konstruktor der Basisklasse Parameter, ist der Konstruktor der abgeleiteten Klasse dafür verantwortlich, die Konstruktoren seiner Basisklassen aufzurufen, wobei der Konstruktor der 'obersten' Klasse zuerst aufzurufen ist. Für unser Beispiel ergibt sich damit der unten dargestellte Konstruktor der Klasse Window.

Window::Window(...):
   WinBase(...), Frame(...), Menu(...) // ctors
{...}

Für die Aufruf-Reihenfolge der Konstruktoren gilt, dass zuerst der Konstruktor der obersten Basisklasse ausgeführt wird und danach die Konstruktoren der nachfolgenden Basisklassen, und zwar in der Reihenfolge, in der die Basisklassen bei der Klassendefinition angegeben wurden. Diese Reihenfolge ist auch bei der Initialisiererliste der 'untersten' Klasse einzuhalten, da ansonsten je nach Compiler eine Reihe von Warnungen ausgegeben wird.


Copyright 2024 © Wolfgang Schröder
E-Mail mit Fragen oder Kommentaren zu dieser Website an: info@cpp-tutor.de
Impressum & Datenschutz