I've tried running the following:
struct B;
struct C;
struct A{
A() { f(this);}
virtual A* f(A* a) {
cout << " A::f(A)" <<endl;
return a;
}
void h() { cout << typeid(*this).name() << endl;}
void g(B* b);
};
struct B:A{
B() { f(this); }
virtual A* f(A* a) {
cout << "B::f(A)" << endl;
return a;
}
virtual B* f(B* b) {
cout << "B::f(B)" << endl;
return b;
}
virtual C* f(C* c) {
cout << "B::f(C)" << endl;
return c;
}
};
struct C: B{};
void A::g(B* b) { cout << typeid(*this).name() << endl; f(b);};
int main(){
B* b = new B();
cout << "------" << endl;
C* c = new C();
cout << "------" << endl;
c->g(b);
return 0;
}
Notice that g() is non virtual so it's chosen during the compilation.
When running this I get the following output:
A::f(A)
B::f(B)
------
A::f(A)
B::f(B)
------
1C
B::f(A) <----- Notice this
Notice that the last line seems to have called f() as if it were dynamically bound but only to the method f() which A knows about (which I think has to do with the fact that g() is statically bound). What I expected to happen was to get B::f(B).
Why is f()'s call in g() computed at compile time?
Overloads have nothing to do with virtual polymorphism. Only A::f(A*)
is virtual and dispatched dynamically. The function B::f(B*)
is entirely unrelated.