`static_cast` von virtueller Basisklasse
-
Hallo,
ich dachte bisher immer, folgender Code sei gültiges C++.
struct B { virtual ~B() {} }; struct D : B { }; int main() { B const& b = D(); D const& d = static_cast<D const&>(b); }Es kompiliert auf jeden Fall problemlos und scheint auch zu funktionieren. Aber jetzt hat mich jemand auf [5.2.9.8] hingewiesen:
C++-Standard schrieb:
An rvalue of type “pointer to cv1
B”, whereBis a class type, can be converted to an rvalue of type “pointer to cv2D”, whereDis a class derived (clause 10) fromB, if a valid standard conversion from “pointer toD” to “pointer toB” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, **andBis not a virtual base class ofD**.(Hervorhebung von mir.)
Mein Weltbild stürzt ein. Oder was übersehe ich da?
/EDIT: Terminologiefrage. Ist obiges vielleicht gar keine virtuelle Basisklasse sondern lediglich eine Basisklasse mit vtable? Ich finde gerade die Begriffsdefinition im Standard nicht, aber folgendes, in 10.3.1.:
A class that declares or inherits a virtual function is called a polymorphic class
-
ich denke es ist ein interface gemeint, also alles pure virtual.
-
Konrad Rudolph schrieb:
/EDIT: Terminologiefrage. Ist obiges vielleicht gar keine virtuelle Basisklasse sondern lediglich eine Basisklasse mit vtable?
Ja, obiges ist wie gesagt eine polymorphe Klasse (Klasse mit virtuellen Funktionen, mit VTable).
Mit virtueller Basisklasse bezeichnet man den Umstand, dass virtuell vererbt wird:
class A : B, virtual C { };
-
Was ist den das? Was bringt virtuelle Vererbung?
-
google mal nach Mehrfachvererbung und "diamond of death".
-
äpfelchen schrieb:
Was ist den das? Was bringt virtuelle Vererbung?
Virtuelle Basisklassen kommen bei Mehrfachvererbung zum Zug.
Hat man zum Beispiel Folgendes:
class Base {}; class Middle1 : public Base {}; class Middle2 : public Base {}; class Derived : public Middle1, public Middle2 {};Hier würde
Basezwei Mal konstruiert, da von jederMiddleaus der Konstruktor aufgerufen wird. Um diese Zweideutigkeit zu umgehen, kann man eine Basisklasse alsvirtualangeben. Diese ist dann "schwächer", wird also vernachlässigt.
-
Ben04 schrieb:
google mal nach Mehrfachvererbung und "diamond of death".
oder auch "dreaded diamond"
-
Nexus schrieb:
Um diese Zweideutigkeit zu umgehen, kann man eine Basisklasse als virtual angeben. Diese ist dann "schwächer", wird also vernachlässigt.
Nein. Wenn du lediglich ein Obejkt virtual erben lässt, ändert das rein gar nichts an dem Problem der Mehrdeutigkeit (welche sich ja auch duch explizite Qualifizierer umgehen lässt).
Das Problem ist eher rein logischer Natur. Warum sollte eine Klasse 2 mal vom genau gleichen Objekt erben.Wenn du aber beide Objekte Mittels virtual erben lässt, wird nicht da eine vernachlässigt, sondern ganz einfach nur eines erstellt.
-
Okay, danke für die Berichtigung. Ich hatte selber noch nie mit Mehrfachvererbung zu tun, deshalb wusste ich es nur noch vage aus der Theorie.