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?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage