Dynamically binding of overridden methods

174 Views Asked by At

I'm trying to understand when the compiler has, or not, all the information needed to decide statically or dynamically how to bind method calls to method definitions.

I read that in Java there is a rule that binds them statically when the method is overloaded and dynamically when it is overridden. I'm playing around with some C++ code and it's not clear to me how it works.

For example, if I have:

class A
{
    public:

    // virtual void p()
    void p() {
        cout << "A::p" << endl;
    }

    void q() {
        p();
    }
};

class B : public A
{
    public:

    void p() {
        cout << "B::p" << endl;
    }
};

a) When I do:

A a;
B b;

a.q();    // output: A::p
b.q();    // output: A::p

I assume the compiler (g++) binds statically b.q() to A.q() and p() (inside A.q()) to A.p(). A.p() is into the context of A.q()

b) But, if I declare A.p() as virtual, the output will be:

a.q();    // output: A::p
b.q();    // output: B::p

Here, I imagine that, b.q() is bound to A.q(), statically as did the previous scenario, but p() inside A.q() is bound to B.p(), that override A.p().

If the rule were the same (that overriding is resolved dynamically), it would imply that the compiler does not have all the necessary information to do it statically.

Why can't the compiler bind the overridden version of the virtual method instead of deferring that decision to the runtime? Which is the lacking information here?

===> Edited <===

It was suggested not to mix Java and C++. I'm reading the Louden & Lambert book "Programming Languages" and the authors compare what bindings look like in both languages. That is the reason why I mentioned them. But, my question is more related to the need for dynamic linking, regardless of language. Why can't the compiler figure out based on the source code how to bind virtual or overridden methods?

1

There are 1 best solutions below

0
On BEST ANSWER

C++ uses virtual method tables to support dynamic dispatch. An instance of a class contains a hidden pointer to a struct containing the function pointers for the virtual methods for that class.

For a simple example:

class A {
public:
    virtual void p();
};

void some_function(A* ap) {
    ap->p();
}

The compiler has no idea ahead of time what code the call to ap->p(); will actually invoke.

some_function could be compiled into object code, sitting in a library or linked to an executable, run and invoke ap-p>();, and execute code that literally didn't exist at the time some_function was compiled.