v05-l4-checkCode

(1/1)

What happen with the following code ?

#include <iostream>
using std::cout, std::endl;

class Base {};

class Derived : public Base {};

void foo(Base* B) {
    cout << "B is a Base object" << endl;
}

void foo(Derived* B) {
    cout << "B is a Derived object" << endl;
}

int main() {
    Base* b = new Derived();
    foo(b);
}

???

In C++, function overloading is always determined statically at compile-time. In this case, the compiler has to know which function to call, depending on the type of b. The declared type of b is Base*, and the compiler has no means to know if we assign the base type to it, or its derived. For instance, if we consider this code :

Base* b = new Base();
// ... part A
b = new Derived();
// ... part B

Since the compiler does not execute the code, it should not know what is the exact type of b in part A or part B.

This is actually why we should use polymorphism instead of overloading here. Let's modify the code and use virtual methods instead of functions :

#include <iostream>
using std::cout, std::endl;

class Base {
public:
    virtual void foo() {
        cout << "B is a Base object" << endl;
    }
};

class Derived : public Base {
    void foo() {
        cout << "B is a Derived object" << endl;
    }
};

int main() {
    Base* b = new Derived();
    b->foo();
}

Now the code outputs "B is a Derived object" as expected.

Note : if you don't declare the foo method as virtual in Base, then it's the same behavior as with function overloading.

This question was inspired from a lecture of the module Wissenschaftliche Programmierung, teached by Prof. Tobias Knopp.