2014-12-13 6 views
5

Ich habe versucht, viel zu finden, dass was ist, wenn nur eine Klasse virtuell in mehrfacher Vererbung gemacht wird? Das Verhalten des Konstruktoraufrufs ist mir in diesem Fall nicht klar. zum Beispiel sagen wir code-Sequenz von Konstruktoraufrufen in mehrfacher Vererbung

#include<iostream> 
using namespace std; 
class grand{ 
public: 
    grand(){cout<<"grandfather"<<endl;} 
}; 
class parent1:virtual public grand{ //virtual used only here 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2: public grand{ 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 
class child:public parent1,public parent2{ 
public: 
    child(){cout<<"child"<<endl;} 
}; 
int main() { 
    child s; 
    return 0; 
} 

Der Ausgang dieses Codes kommt als

grandfather 
parent1 
grandfather 
parent2 
child 

aber in obigen Code, wenn wir diese

class parent1:virtual public grand{ 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2: public grand{ 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 

dieser

class parent1:public grand{ //virtual removed from here 
public: 
    parent1(){cout<<"parent1 "<<endl;} 
}; 
class parent2:virtual public grand{ //virtual is added here 
public: 
    parent2(){cout<<"parent2"<<endl;} 
}; 
ändern

Ausgabe wird angezeigt als

grandfather 
grandfather //why parent1 constructor is not called here? 
parent1 
parent2 
child 

Mein Anliegen ist, warum parent1 Konstruktor nicht nach Großvater aufgerufen wird?

+0

möglich Duplikat von [Virtual Inheritance, eine Klasse genug?] (Http://stackoverflow.com/questions/13752482/virtual-heritance-one-class-enugh) – Mikhail

+1

Nein, das ist über * Reihenfolge der Anrufe * nicht über * Teilen * von selbst. –

Antwort

5

Der Standard sagt [C++ 11 Abschnitt 12.6.2/10], dass:

In einem nicht zum Delegieren Konstruktor Initialisierung schreitet in der folgenden Reihenfolge :

- Erste und Nur für den Konstruktor der am weitesten abgeleiteten Klasse werden virtuelle Basisklassen in der Reihenfolge initialisiert, in der sie auf einer Tief-zuerst-links-nach-rechts-Traversierung des gerichteten azyklischen Graphen von Basisklassen erscheinen, wobei "von links nach rechts "Ist die Reihenfolge des Auftretens der Basisklassen i n die abgeleitete Klassenbasis-Spezifiziererliste.

- Dann werden direkte Basisklassen in der Reihenfolge der Deklaration initialisiert als sie in der Basis-Bezeichner-Liste (unabhängig von der Reihenfolge des mem-initializers) erscheinen.

- Dann werden nicht statische Datenelemente in der Reihenfolge initialisiert, in der sie in der Klassendefinition deklariert wurden (wiederum unabhängig von der Reihenfolge der Mem-Initialisierer).

- Schließlich wird die Compound-Anweisung des Konstruktors ausgeführt.

So werden Ihre virtuellen Basisklassen immer zuerst erstellt ... Dies ist wirklich wichtig im Fall der virtuellen Basisklassenfreigabe.

+0

Danke.Wie Sie sagten, virtuelle Klassen zuerst gebaut, aber nach dem Lesen dieser immer noch nicht klar, warum "parent1" heißt nicht gleich nach "Großvater" .Können Sie bitte ein Beispiel in Ihrer Antwort bitte? – Ankur

+1

Ok, Sie müssen zuerst die virtuelle Basisklasse für 'parent2' erstellen (Regel 1). Dann müssen Sie "parent1" und dann "parent2" in dieser Reihenfolge erstellen, wie sie deklariert sind (Regel 2). Um "Eltern1" zu erstellen, müssen Sie zuerst eine "große" Instanz erstellen, aber nicht die virtuelle (Regel 2). Dies wird Ihnen die folgende Reihenfolge geben: 'grand' (virtuell),' grand' (für parent1), 'parent1',' parent2' (mit dem am Anfang gebauten virtuellen grand) und dann das 'child'. –

+0

Danke, hab das jetzt :) – Ankur

Verwandte Themen