Overloading in Derived Classes
If I overload a function in a base class, can I also overload it in a derived class?
Yes, if a function is overloaded in a base class, you can also overload it in a derived class. However, there's a subtle point to be aware of: the overloads in the derived class will hide the overloads in the base class, even if they have different parameters. This is due to a C++ feature called "name hiding".
Consider this example:
#include <iostream>
#include <string>
class Base {
public:
void Print(int x) {
std::cout << "Base: Print(int)\n";
}
void Print(double x) {
std::cout << "Base: Print(double)\n";
}
};
class Derived : public Base {
public:
void Print(std::string x) {
std::cout << "Derived: Print(string)\n";
}
};
int main() {
Derived obj;
obj.Print(10);
obj.Print(10.0);
// calls Derived::Print(string)
obj.Print(std::string("abc"));
}error: no matching function for call to 'Derived::Print(int)'
error: no matching function for call to 'Derived::Print(double)'In this code, even though Base has overloads of Print that take int and double, these are hidden by the Print overload in Derived. When you call Print on a Derived object, the compiler only considers the overloads in Derived.
To make the overloads from Base available in Derived, you need to use the using keyword:
class Derived : public Base {
public:
// bring all overloads of Print from
// Base into scope
using Base::Print;
void Print(std::string x) {
std::cout << "Derived: Print(string)\n";
}
};Now, when you call Print on a Derived object, the compiler will consider all overloads from both Derived and Base:
int main() {
Derived obj;
// calls Base::Print(int)
obj.Print(10);
// calls Base::Print(double)
obj.Print(10.0);
// calls Derived::Print(string)
obj.Print(std::string("abc"));
}Base: Print(int)
Base: Print(double)
Derived: Print(string)The using Base::Print; statement brings all overloads of Print from Base into the scope of Derived, essentially "unhiding" them.
This is a common pitfall when overloading functions in derived classes. If you want the base class overloads to be available, remember to use the using keyword. Otherwise, the derived class overloads will hide the base class overloads, which can lead to unexpected behavior or compilation errors.
Understanding Overload Resolution
Learn how the compiler decides which function to call based on the arguments we provide.