Sind mehrere geerbte Konstruktoren mehrfach aufgerufen?
Sind mehrere geerbte Konstruktoren mehrfach aufgerufen? Und in welcher Reihenfolge werden die Konstruktoren aufgerufen? Dies tut hängt von der Reihenfolge, in der vererbungsliste?
Hier ist ein Beispiel (es ist nur, dass die situation klar, keine real-life-Beispiel).
class Base {};
class DerivedBaseOne : public Base {};
class DerivedBaseTwo : public Base {};
class Derived : public DerivedBaseTwo, public DerivedBaseOne
{};
//somewhere in the code, is Base() called two times here?
Derived * foo = new Derived();
Ist die Base()
Konstruktor zweimal aufgerufen? Und in welcher Reihenfolge werden die Konstruktoren aufgerufen? Basis ersten? Oder DerivedBaseOne()
oder DerivedBaseTwo()
ersten?
- Sie kann auch das denken der virtuellen Vererbung das wäre etwas anders von der normalen Vererbung.
- Geerbte Konstruktoren ist ein feature von c++11 und bedeuten ganz anders zur Sache.
- Verwandte: en.wikipedia.org/wiki/Diamond_problem
- ideone.com/9ghzb
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Art und Weise Sie es schreiben,
Derived
hat zwei verschiedene Unterobjekte vom TypBase
, und jeder bekommt seinen eigenen Konstruktor aufgerufen, aus dem jeweiligenDerivedBaseXXX
Konstruktor des Unterobjekt. Die Reihenfolge der Aufrufe folgt der Reihenfolge der Deklaration.Durch den Kontrast, der Sie erklären
DerivedBaseXXX : virtual public Base
, dann gibt es nur eineBase
Unterobjekt, und der Konstruktor wird aufgerufen, aus dem die meisten abgeleiteten Objekt, d.h. von derDerived
Objekt.(Zur Erklärung ein bisschen genauer: Eine (möglicherweise einzeln-Erben) Klasse konstruiert, indem man zuerst 1) Aufruf der Basisklasse s Konstruktor, dann 2) Aufruf der Konstruktoren aller member-Objekte in der Reihenfolge der Deklaration, und schließlich 3) die Ausführung des Konstruktor-Funktion Körper. Dies gilt rekursiv, und für Mehrfachvererbung, die Sie gerade ersetzen (1) durch den Aufruf alle der Basisklasse Konstruktoren in der Reihenfolge, in der die erbschaft deklariert wurde. Nur virtuelle Vererbung fügt einen echten zusätzlichen Komplikation hier.)
Die Reihenfolge der Konstruktor-Aufrufe für Ihre Vererbungshierarchie werden:
Die Reihenfolge ist in der Tat gut definiert und hängt von der Reihenfolge, in der Sie erwähnen die Ableitung für die Basis-Klassen und die Reihenfolge, in der Sie erklären, die Mitglieder in der Klasse für die Mitglieder. (Sehen Sie den Hinweis aus der C++ Standard unten.)
Hat die Basis () - Konstruktor aufgerufen werden, zweimal?
JA
Den
Base()
Konstruktor der Klasse aufgerufen wird, hier zweimal, weil zwei KlassenDerivedBaseTwo()
undDerivedBaseOne()
daraus ziehen, so dass die Basisklasse der Konstruktor wird aufgerufen, sobald für jeden von Ihnen. IhreDerived
Klasse hat zwei verschiedeneBase
Teilobjekte durch mehrere Pfade (durchDerivedBaseOne()
und die anderen aberDerivedBaseTwo()
).Die Hierarchie der Klassen, die Sie haben mit Mehrfachvererbung ist ungewöhnlich, und es führt zu einem problem genannt Rautenförmige Vererbung Problem. Um dieses problem zu vermeiden C++ - Einführung in das Konzept der Virtuelle Basisklasse.
Referenz:
C++03-Standard: 12.6.2/5, Initialisieren Basen und Mitglieder
Base
Klasse in diesem Fall nicht zweimal genannt, aber nur einmal. Virtuelle Vererbung, die nicht tatsächlich in dem code in Frage, der dies ermöglicht. Dennoch, code in der Frage ist nicht kompilierbar, da die virtuelle Vererbung nicht verwendet wird, die notwendig ist, in einem Fall von Diamant-Vererbung.b
verwendet den Wert von Mitglieda
im direkten Initialisierung, seine Erklärung muss es gelingen, dass dera
usw.).Dies ist beantwortet: http://www.parashift.com/c++-faq-lite/mehrfach-Vererbung.html#faq-25,14, im
Seit Ihr Mehrfachvererbung Erklärung listet
DerivedBaseTwo
erste, seine Konstruktion Auftrag wird ausgeführt werden, bevorDerivedBaseOne
's.Also in Ihrem
Derived
KlasseDerivedBaseTwo
und seine Kette zuerst erstellt wird, ist:1 -
Base
dannDerivedBaseTwo
Dann
DerivedBaseOne
und seine Kette:2 -
Base
dannDerivedBaseOne
Dann:
3 -
Derived
erstellt wird, nachdem alles andere.Auch, mit Mehrfachvererbung werden, eingedenk der Diamond Inheritance Problem