Виртуальное наследование С++

Проблема:

class Base {
public:
  Base(Base* pParent);
  /* implements basic stuff */
};

class A : virtual public Base {
public:
  A(A* pParent) : Base(pParent) {}
  /* ... */
};

class B : virtual public Base {
public:
  B(B* pParent) : Base(pParent) {}
  /* ... */
};

class C : public A, public B {
public:
  C(C* pParent) : A(pParent), B(pParent) {} // - Compilation error here
  /* ... */
};

В указанной позиции gcc жалуется, что она не может соответствовать вызову функции Base(), то есть конструктору по умолчанию. Но C не наследует непосредственно от Base, только через A и B. Итак, почему gcc жалуется здесь?

Идеи? ТИА /Rob

Ответ 1

virtual базовые классы отличаются тем, что они инициализируются самым производным классом, а не промежуточными базовыми классами, которые наследуются от виртуальной базы. Какой из возможных множественных инициализаторов будет правильным выбором для инициализации одной базы?

Если построенный наиболее производный класс не перечисляет его в списке инициализации его члена, тогда виртуальный базовый класс инициализируется его конструктором по умолчанию, который должен существовать и быть доступным.

Обратите внимание, что виртуальный базовый идентификатор разрешен для использования в списке инициализаторов конструктора, даже если он не является прямой базой рассматриваемого класса.

Ответ 2

Вам нужно явно вызвать конструктор для Base из C:

class C : public A, public B {
public:
C(C* pParent) : Base(pParent), A(pParent), B(pParent) {}
/*... */
};

Ответ 3

Если вы объявляете пользовательский конструктор, конструктор по умолчанию отключен. В виртуальном наследовании вам нужно вызвать фактически унаследованный конструктор напрямую, потому что иначе он не знал бы, следует ли инициализировать A или B.