Пожалуйста, обратите внимание на следующий код:перегруженные вызов виртуальной функции разрешения
class Abase{};
class A1:public Abase{};
class A2:public A1{};
//etc
class Bbase{
public:
virtual void f(Abase* a);
virtual void f(A1* a);
virtual void f(A2* a);
};
class B1:public Bbase{
public:
void f(A1* a);
};
class B2:public Bbase{
public:
void f(A2* a);
};
int main(){
A1* a1=new A1();
A2* a2=new A2();
Bbase* b1=new B1();
Bbase* b2=new B2();
b1->f(a1); // calls B1::f(A1*), ok
b2->f(a2); // calls B2::f(A2*), ok
b2->f(a1); // calls Bbase::f(A1*), ok
b1->f(a2); // calls Bbase::f(A2*), no- want B1::f(A1*)!
}
Мне интересно знать, почему C++ выбирает разрешить вызов функции на последней строке Приведение к базовому типу в this
указатель объекта к основанию класс, а не повышать значение аргумента f()
? Есть ли способ, которым я могу получить поведение, которое я хочу?
Спасибо - как я понимаю, дело в том, что разрешение виртуального f() для вызова происходит во время компиляции, основываясь на аргументе, предоставленном f(). Итак, на последней строке компилятор уже решил, что будет вызван f (A2 *). Вызываемая тогда версия f (A2 *) зависит от того, на какой указатель времени выполнения указывается. Здесь, поскольку класс B1 не переопределяет f (A2 *), вызывается версия базового класса. – stw
@stw, совершенно правильный. –