virtual public Vererbung
-
Hi,
ich bin gerade mal auf so ein Fragment gestoßen
class B : virtual public A .....
und frage mich, was das soll (scheint ja gültiger Code zu sein).
Wenn A eh schon eine virtuelle Klasse (eine Klasse mit virtuellen Methoden) ist, warum dann nochmal hinschreiben? Wenn sie keine ist, dann ändert sich doch kein Stück an A.
Also kann das doch nur Auswirkungen auf B haben?? Nur was sollte das sein? Destruktor automatisch virtual? Würde keinen Sinn machen, da dann eh alle Basisklassen virtuell sein sollten (public Vererbung -> virtueller Destruktor nach Meyers). Dazu zwingt einen zwar keiner, aber schlechter Code ist das schon...
Ist es also nur "informativ"? Oder veraltet? Ich bin verwirrt.
-
Meinst du du bist der erste der dieses Konstrukt entdeckt hat?
-
Sinnvoll bei mehrfachvererbung!
Class Base
Class GFrame:public Base
Class BFrame:public Base
Class MyFrame:public GFrame,public GFramejetzt hätte MyFrame die public und protected member von Base doppelt, durch virtuelle vererbung passiert das nicht....
-
Wenn A eh schon eine virtuelle Klasse (eine Klasse mit virtuellen Methoden) ist
Erster Denkfehler: eine Basis-Klasse mit virtuellen Methoden ist keine virtuelle Basisklasse. Eine virtuelle Basisklasse ist eine Klasse von der virtual geerbt wird.
Der Unterschied zwischen virtueller- und normaler Vererbung: Normale Vererbung bedeutet Komposition-by-Value. Virtuelle Vererbung hingegen Komposition-by-Reference. Der Unterschied wird erst deutlich und relevant, wenn eine abgeleitete Klasse mehrmals die selbe Basisklasse hat:
A / \ B C \ / D
Bei normaler Vererbung enthält jedes D zwei A-Objekte. Eins über den Weg B-A und eins über den Weg C-A. Das ist nicht immer was man will und hier kommt virtuelle Vererbung ins Spiel. Lässt man B und C virtuell von A erben, so enthält D nur ein A-Objekt.
Ein mögliches Objektlayout für D bei normaler Vererbung: D = ABAC
Ein mögliches Objektlayout für D bei virtueller Vererbung: D = A*BA*CAEs gibt noch ein paar Feinheiten bei der virtuellen Vererbung (Konstruktion durch die am weitesten abgeleiete Klasse, Dominanzregel bei der Überschreibung...), aber der Hauptunterschied ist der den ich beschrieben habe.
-
Diamond-Shape... bääh...
Aber verständlich. Sind jetzt also alle, die von Base ableiten, dafür verantwortlich, virtual public abzuleiten?
-
Sind jetzt also alle, die von Base ableiten, dafür verantwortlich, virtual public abzuleiten?
Richtig. Deshalb ist virtuelle Vererbung auch nicht transparent. Du musst vorher bereits wissen wie deine Hierarchie aussehen wird. Du kannst also nicht B und C normal von A ableiten und dann später ohne Änderung in D nur ein A Objekt haben. Das geht nur, wenn du die Vererbungsbeziehung zwischen B-A und C-A änderst.
-
// Oberste Basisklasse Class Base {....}; // 1. virtuell abgeleitete Klasse Class GFrame: virtual public Base {....}; // 2. virtuell abgeleitete Klasse Class BFrame: virtual public Base {....}; // Endgültige Klasse Class MyFrame: virtual public GFrame, public BFrame {....};
Klassendiagramm:
Base
virtual / \ virtual
abgeleitet / \ abgeleitet
/ \
GFrame BFrame
\ /
abgeleitet \ / abgeleitet
\ /
MyFrameso ok?
-
Klassendiagramm:
Base virtual / \ virtual abgeleitet / \ abgeleitet / \ GFrame BFrame \ / abgeleitet \ / abgeleitet \ / MyFrame
so?