3

In unten Programm im Fall, wenn ich die Reihenfolge in abgeleiteten Klasse "D" ändern, dann bekomme ich andere Reihenfolge der Konstruktoren der Basisklasse.Nicht in der Lage zu verstehen, virtuelle Basisklasse Konstruktor im Falle von Multilevel-Vererbung

#include <iostream> 

    using namespace std; 

    class A { 
     public : 
      A() 
      { 
       cout << "A()" <<endl; 
      } 
    }; 

    class B : virtual A{ 
     public : 
      B() 
      { 
       cout << "B()" << endl; 
      } 
    }; 

    class C : virtual B{ 
     public : 
      C() 
      { 
       cout << "C()" << endl; 
      } 
    }; 

Case (1) 
======== 
    class D : public A, public B, public C 
    { 

    }; 

    int main() 
    { 
     D d; 
     return 0; 
    } 
OUTPUT : 
A() 
B() 
A() 
B() 
C() 

Case (2) 
======== 
    class D : public C, public B, public A 
    { 

    }; 

    int main() 
    { 
     D d; 
     return 0; 
    } 
OUTPUT : 
A() 
B() 
C() 
B() 
A() 

Case (3) 
======== 
    class D : public B, public A, public C 
    { 

    }; 

    int main() 
    { 
     D d; 
     return 0; 
    } 
OUTPUT : 
A() 
B() 
B() 
A() 
C() 

Bitte sagen Sie uns, wie Konstruktoren im Falle von virtuellen Klassenkonzepten aufgerufen werden.

+0

Nicht sicher, wenn Sie verstehen, wie virtuelle Vererbung funktioniert: http://ideone.com/Ptaf5u – kfsone

+0

Warum verwenden Sie private Vererbung? – curiousguy

Antwort

0

Die virtuellen Basen werden immer zuerst in der DFS-Nachfolge initialisiert. Dies garantiert, dass die virtuellen A- und B-Basen zuerst initialisiert werden und A vor B, da B von A abgeleitet ist. Danach werden die drei nicht virtuellen Basen A, B, C einfach in der Deklarationsreihenfolge initialisiert, wie Sie es erwarten würden.

2

Bitte sagen Sie uns, wie Konstruktoren im Falle von virtuellen Klassenkonzepten aufgerufen werden.

Gemäß der initialization order wird die virtuelle Basisklasse zuerst initialisiert.

1) Wenn der Konstruktor für die meisten abgeleitete Klasse ist, virtuelle Basis Klassen in der Reihenfolge initialisiert werden, in dem sie in depth-first links-nach-rechts-Traversal der Basisklassendeklarationen erscheinen (von links nach rechts bezieht sich auf den Auftritt in Basis-Bezeichner Listen)

2) Dann werden direkte Basisklassen in von links nach rechts, um initialisiert als sie in Klasse dieser Basis-Bezeichner Liste erscheinen

3) Dann werden nicht statische Datenelemente in der ReihenfolgeinitialisiertDeklaration in der Klassendefinition. Schließlich

4) wird der Körper des Konstruktor ausgeführt

In allen drei Fällen Klasse D erbt von A, B und C, sind da zwei virtuelle Basisklassen in D, dh A erbte über B und C, und B erbte über C. Und A wird zuerst initialisiert werden, weil es die am meisten Basisklasse ist, so dass für alle 3 Fälle zuerst A() und B() ausgedruckt werden.

Danach werden die direkten Basisklassen in der Reihenfolge von links nach rechts initialisiert. Für den ersten Fall werden sie A()B()C(), für den zweiten Fall sein, sie B() sein werden C()A(), für den dritten Fall werden sie B()A()C() sein.