2010-08-19 2 views
16

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

Настоящая диаграмма алмаза (простейшая с единственным изменением конструктора по умолчанию) не компилируется (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

ответ

3

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

22

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

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

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

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

бесстыдно скопирована с here :-)

1

В статье д-р Доббс Multiple Inheritance Considered Useful объясняет различные способы борьбы с этим. Рекомендация в основном заключается в предоставлении конструкторов по умолчанию и методов init(). Он добавляет больше работы B и C, но предотвращает D от необходимости знать о А.

+1

Оставляя D не зная, А это, конечно, желательно. К сожалению, решение «init()» имеет недостаток: конструктор A будет вызываться дважды (один раз по B и C), который может иметь побочные эффекты (особенно если используются статические элементы). Кроме того, если разработчик создает «класс D: public A {}', метод init() может вообще не вызываться, оставив объект в неинициализированном состоянии. – Marste

0

вам нужна конструкция explict индивидуального вызова как это:

D(int i) : A(i), B(i), C(i) {} 
Смежные вопросы