Я изучаю темы, связанные с множественным наследованием. Я придумал следующий код, и не мог полностью понять механизм позади него:Как работает полиморфизм с множественным наследованием?
struct root
{
virtual void vfunction(){ /* root version */ }
};
struct mid1:public root
{
virtual void vfunction(){ /* mid1 version */ }
};
struct mid2:public root
{
virtual void vfunction(){ /* mid2 version */ }
};
struct inheritMulti:public mid1, public mid2
{
void ambiguityMethod(){
vfunction(); // error: ambiguous
}
void method1(){
mid1& t = *this;
t.vfunction();
}
void method2(){
mid2& t = *this;
t.vfunction();
}
};
ambiguityMethod
ошибка, очевидно. Однако функция вызывает как method1
, так и method2
смущает меня. Они также являются вызовом виртуальной функции, а t
имеет тип inheritMulti
. Поэтому они должны назвать inheritMulti
версию vfunction
, но поскольку inheritMulti
не имеет собственной версии, я не знаю, что произойдет. И получается, что звонок в method1
вызывает версию mid1
, а звонок в method2
вызывает версию mid2
. Это что-то неопределенное и произошло только в моем компиляторе? Если нет, то почему это работает так? Как vtable справляется с такой ситуацией? Благодаря!
Спасибо, что помогли в первую очередь. Я сам искал связанные темы, так что да, я знаю «проблему с алмазами». Но я думаю, что мой вопрос отличается от этого. Моя основная проблема заключается в том, является ли поведение «виртуального вызова функции» в method1
и method2
четко определенным или неопределенным стандартом. В компиляторе он вел себя так, как я упоминал выше, но это поведение, обещанное стандартом? Если он четко определен, почему он вызывает mid1
и «mid2» версию соответственно? (Интуитивное мышление будет называть версию inheritMulti
, так как тип t
на самом деле inheritMulti
) А также, как большинство компиляторов справляются с этой ситуацией? Странно, что вызов виртуальной функции в method1
и method2
вызывает различные функции. Еще раз спасибо!
что вы думаете, что должно произойти здесь? – Creris