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.