c ++ виртуальное наследование - PullRequest
22 голосов
/ 24 января 2010

Проблема:

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 жалуется?

Идеи?TIA / Rob

Ответы [ 3 ]

46 голосов
/ 24 января 2010

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

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

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

8 голосов
/ 24 января 2010

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

class C : public A, public B {
public:
C(C* pParent) : Base(pParent), A(pParent), B(pParent) {}
/*... */
};
5 голосов
/ 24 января 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...