Aufrufen des überladenen Konstruktors einer virtuellen Basisklasse
Gibt es eine (praktische) Möglichkeit, die normale (virtuelle) Aufrufreihenfolge von Konstruktoren zu umgehen?
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;
}
Ausgabe
aufruf A ()
calling B (int)
calling C (int)
calling D (int)
Was ich haben möchte ist so etwas wie:
aufruf A (int)
calling B (int)
calling C (int)
calling D (int)
Wie Sie sehen, handelt es sich um eine virtuelle Vererbung, bei der der Konstruktor von D zuerst den Konstruktor von A aufruft. Da jedoch kein Parameter angegeben ist, ruft er A () auf. Da ist das const int i das muss initialisiert werden, also habe ich ein Problem.
Was ich tun möchte, ist, die Vererbungsdetails von C zu verbergen, deshalb suche ich nach einer Möglichkeit, um zu vermeiden, A (i) in der Initialisierungsliste von D (und jedem abgeleiteten) Konstruktor aufzurufen. [edit] In diesem speziellen Fall kann ich davon ausgehen, dass es nur nicht-virtuelle untergeordnete Klassen mit einfacher Vererbung von C gibt (da D eine ist). [/bearbeiten
[bearbeiten
Virtuelle Basisklassen werden initialisiert, bevor nicht-virtuelle Basisklassen initialisiert werden, sodass nur die am häufigsten abgeleitete Klasse virtuelle Basisklassen initialisieren kann. - James McNellis
Das ist genau der Punkt, ich nicht möchte, dass die am häufigsten abgeleitete Klasse den Konstruktor der virtuellen Basisklasse aufruft.[/bearbeiten
Betrachten Sie die folgende Situation nicht im obigen Codebeispiel dargestellt):
A
/ \
B0 B1
\ /
C
|
D
Ich verstehe, warum C den ctor von A (Mehrdeutigkeit) aufrufen muss, wenn Sie C instanziieren, aber warum muss D ihn aufrufen, wenn Sie D instanziieren?