Weil besser als gut!

Mehrfachvererbung (C++)Inhaltsverzeichnis DefinitionMehrfachvererbung (multiple inheritance) erlaubt, eine Klasse aus mehr als einer direkten Basisklasse abzuleiten. Syntaktisch ist dies zunächst einfach, die Basisklassen werden mit Angabe der jeweiligen Ableitungsart (public, private, protected) und mit Komma separiert aufgelistet: C++ class AB : public A, public B { ... }; Mehrdeutigkeiteneinfache MehrdeutigkeitenDurch identisch bezeichnete Elemente treten Mehrdeutigkeiten auf, die mit dem Bereichsoperator aufzulösen sind. Sei in A und B je eine Methode machWatt() definiert, so können diese für ein Objekt ab der Klasse AB wie folgt aufgerufen werden: C++ ab.A::machWatt(); ab.B::machWatt(); Der Aufruf ab.machWatt(); würde nicht kompiliert werden. Alle eindeutig bezeichneten Elemente können natürlich direkt verwendet werden, denn ab ist ein Objekt der Klasse A und der Klasse B, besitzt also ein Subobjekt aus A und ein Subobjekt aus B. mehrfach indirekte BasisklassenEs ist nicht möglich, dass eine Klasse direkt mehrfach als Basisklasse verwendet wird: C++ class AB : public A, public B, public A { ... }; Indirekt ist dies sehr wohl möglich, in den allermeisten Fällen aber gar nicht erwünscht:
virtuelle BasisklassenVirtuelle Basisklassen lösen das Problem der mehrfach indirekt vererbten Klassen. Die Bezeichnung virtuell ist hier unglücklich, dennoch wird auch hier das keyword virtual verwendet. Kennzeichnet man bei der Deklaration der Klassen A und B die Basisklasse Basis als virtual, so entsteht ein anderes Vererbungsdiagramm (s. nächste Seite): C++ class A : virtual public Basis { ... }; class B : virtual public Basis { ... }; Basis wird virtuelle Basisklasse, wenn die Klassen A und B sie als solche verwenden. Auswirkung hat dies aber erst für die Klasse AB: die Basis-Elemente sind jetzt nur noch einfach vorhanden. zeigWatt() kann nun auf str direkt zugreifen, oder aber immer noch mit A::str oder B::str InitialisierungNormalerweise kann ein Konstruktor in seiner Initialisierungsliste nur Konstruktoren seiner direkten Basisklasse(n) auflisten. Parameter können so bis zur Initialisierungsliste der Basisklasse weitergereicht werden. Ist die Basisklasse aber virtuell, entsteht wieder eine Mehrdeutigkeit: wer zuletzt seinen Wert 'durchreicht', hätte gewonnen - der Compiler lässt diese Situation natürlich nicht zu, es gelten folgende Sonderregeln: SonderregelnSonderregeln zur Initialisierung virtueller Basisklassen:
Beispiel
virtuelle Methoden in virtuellen BasisklassenEine weitere Mehrdeutigkeit entsteht, wenn die Klassen A und B z.B. eine in Basis als virtuell deklarierte Methode f() implementieren. Da diese beiden Versionen von f() naturgemäß eine identische Signatur haben, sind sie in AB nur durch explizite Verwendung des Bereichsoperators zu unterscheiden. Zweck der MehrfachvererbungDie Notwendigkeit der Mehrfachvererbung ist umstritten, eine Mehrfachvererbung erhöht die Komplexität eines Programms. Fast alle Probleme lassen sich auch ohne Mehrfachvererbung lösen (z.B. auch durch Aggregate, wenn die öffentliche Schnittstelle nicht weiter benötigt wird). "Sie können sich MV als eine Eigenschaft der Programmiersprache 'von geringerer Bedeutung' vorstellen, die in Ihre täglichen Entscheidungen hinsichtlich des Entwurfs nicht einfließen sollte." (Bruce Eckel) Häufiger als in anderen OOP-Sprachen entsteht in C++ der Bedarf an MV dadurch, dass C++ Klassenhierarchien i.A. keine gemeinsame Basis haben. Andere SprachenIn Smalltalk, Java und C# wird alles aus Object abgeleitet, so dass eine breite gemeinsame Basis immer gegeben ist. Ein 'Zusammensuchen' einzelner Eigenschaften durch MV ist oftmals nicht notwendig. ReparaturEine anerkannt sinnvolle Verwendung der MV ist die Reparatur von Schnittstellen. Angenommen, Sie haben eine Klasse Segelboot erworben und möchten, dass Segelboote nun auch an der vorhandenen Hafensimulation teilnehmen. Dies ist aber nur für aus ContainerSchiff abgeleitete Klassen möglich. Die MV erlaubt, diesen Mangel zu beheben, ohne die schon existierenden Klassen ändern zu müssen! Mit diesem Verfahren können auch andere Defekte nachträglich behoben werden, z.B. bei einer unvollkommenen Definition der abstrakten Basisklasse: kein virtueller Destruktor, bestimmte Methode ist nicht virtuell, Methode fehlt, etc. |
Zahlen & Daten
Publish |