Search code examples
c++inheritancepolymorphismoverridingvirtual

Why is this virtual method's implementation chosen during compile time?


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?


Solution

  • 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.