Gibt es eine (praktische) Möglichkeit, die normale Aufrufreihenfolge des virtuellen Konstruktors zu umgehen?Aufruf des überladenen Konstruktors einer virtuellen Basisklasse
Beispiel:
class A
{
const int i;
public:
A()
: i(0)
{ cout << "calling A()" << endl; }
A(int p)
: i(p)
{ cout << "calling A(int)" << endl; }
};
class B
: public virtual A
{
public:
B(int i)
: A(i)
{ cout << "calling B(int)" << endl; }
};
class C
: public B
{
public:
C(int i)
: A(i), B(i)
{ cout << "calling C(int)" << endl; }
};
class D
: public C
{
public:
D(int i)
: /*A(i), */ C(i)
{ cout << "calling D(int)" << endl; }
};
int main()
{
D d(42);
return 0;
}
Output:
Aufruf A()
Aufruf B (int)
Aufruf C (int)
Aufruf D (int)
Was ich haben will, ist so etwas wie:
A (int) Aufruf
Aufruf B (int)
Aufruf C (int)
Aufruf D (int)
Wie Sie sehen, ist eine virtuelle Vererbung beteiligt, die dazu führt, dass der Konstruktor von D zuerst den Konstruktor von A aufruft, aber da kein Parameter angegeben ist, ruft er A() auf. Es gibt die const Int i, die Initialisierung benötigt, also habe ich ein Problem.
Was ich tun möchte ist, die Vererbung Details von C zu verstecken, deshalb suche ich nach einer Möglichkeit zu vermeiden, A (i) in D's (und jedem abgeleiteten) Konstruktor Initialisierungsliste zu nennen. [edit] In diesem speziellen Fall kann ich annehmen, dass es nur nicht-virtuelle Einzelvererbungs-Kindklassen von C gibt (wie D ist eins). [/ Edit]
[Bearbeiten]
Virtuelle Basisklassen initialisiert werden, bevor irgendwelche nicht-virtuellen Basisklassen initialisiert werden, so dass nur die abgeleitete Klasse virtuelle Basisklassen initialisieren. - James McNellis
Das ist genau der Punkt, ich nicht wollen die abgeleitete Klasse die virtuelle Basisklasse Konstruktor aufzurufen.
A
/\
B0 B1
\/
C
|
D
Ich verstehe, warum C die Ctor von A (Mehrdeutigkeit), wenn Sie anrufen hat: [/ edit]
Betrachten Sie die folgende Situation (nicht im Codebeispiel oben dargestellt) instanziieren C, aber warum muss D es nennen, wenn es D instanziiert?
Ich glaube nicht, dass Ihr Codebeispiel mit der von Ihnen bereitgestellten Ausgabe übereinstimmt. Sind Sie sicher, dass Sie d mit der Anweisung "D d" instanziiert haben? ? –
sry, ich habe den Parameter vergessen .... es ist D d (42) jetzt. Vielen Dank. – dyp
Ok, das scheint fairer zu sein :-) Darf ich fragen, warum Sie die "Dreaded Diamond" -Architektur verwenden wollen? Können Sie Ihren Code nicht auf andere Weise reorganisieren? –