Проблема в том, что трудно описать, поэтому код размещен спереди для лучшей ясности.Множественное наследование Виртуальная вызов Ambiguity
struct Base
{
int b;
virtual void foo(){cout << b << endl;}
Base(int x) : b(x){}
};
struct Derived1 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived1() : Base(1){}
};
struct Derived2 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived2() : Base(2){}
};
struct MultiInheritance : Derived1, Derived2
{
void bar1()
{
//needs to access Derived1's Base foo()
}
void bar2()
{
//needs to access Derived2's Base foo()
}
};
Предположим, что в какой-то странный причудливый сценарий, я хотел бы базовый класс MultiInheritance
, который имеет два базовых класса Derived1
и Derived2
, которые имеют общую невиртуальном базового класса Base
.
Есть два Base
в MultiInheritance
, как указать, который Base
класс Я хотел бы получить доступ в MultiInheritance
?
Вышеприведенный код, кажется, работает нормально, произнося несколько раз, но я не уверен, если это определено поведением или нет. Если да, то как это реализовано компилятором для удовлетворения потребностей полиморфизма? С одной стороны, вызовы virtual
должны приводить к одной и той же таблице функций virtual
, а с другой, если она не выводит разные ответы.
EDIT
Я хотел бы подчеркнуть, что Base
классов должны быть невиртуальным
EDIT2
глубоких извинений, я серьезно исказил себя. Приведенный выше код лучше отражает мой первоначальный вопрос.
Какой из них вы считаете * правильный * 'Base'? Или ваш вопрос, как сделать так, чтобы существовала только одна «База»? – Barry
Ваш анализ верен, и компилятор построит правильную таблицу vtable, отражающую существование двух базовых классов. Чтобы этого избежать, вам нужно виртуальное наследование, и структура vtable станет более сложной. –
В вашем примере нет двусмысленности, он ведет себя точно так же, как в книге. «Виртуальная таблица» - это деталь реализации. Никто не говорит нигде, что каждая реализация должна иметь один vtbl для каждого класса или что для каждой сигнатуры функции должна быть одна запись в каждой таблице vtable. На самом деле крайне вероятно, что хотя бы одно из приведенных выше неверно для любой реализации, использующей vtables. –