Подтвердить что ты не робот

Конструктор по умолчанию и виртуальное наследование

Возможно ли иметь виртуальное наследование для класса, не предоставляющего конструктор по умолчанию?

Настоящая диаграмма алмаза (самая простая с единственным изменением конструктора по умолчанию) не компилируется (g++ 4.4.3).

class A {
 public: 
  A(int ) {}
};
class B : virtual public A {
 public:
  B(int i) : A(i) {}
};
class C : virtual public A {
 public:
  C(int i) : A(i) {}
};
class D : public B, public C {
 public:
  D(int i) : B(i), C(i) {}
};

Спасибо, Francesco

4b9b3361

Ответ 1

Вам нужно явно вызвать конструктор A здесь

 D(int i) : A(i), B(i), C(i) {}

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

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

Бесстыдно скопировано из здесь: -)

Ответ 2

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

Ответ 3

Статья доктора Доббса Многократное наследование считается полезным объясняет различные способы борьбы с этим. Рекомендация в основном заключается в предоставлении конструкторов по умолчанию и методов init(). Он добавляет больше работы для B и C, но не позволяет D узнать о A.

Ответ 4

вам нужно вызывать вызов A, как это:

D(int i) : A(i), B(i), C(i) {}