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.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Passing Non-Const References to Overloaded Functions
Why does the compiler prefer a non-const reference parameter over a const reference when I pass a non-const variable?
Overloading Functions with Default Arguments
Can I overload functions that differ only in their default arguments?
Debugging Overload Resolution Failures
How can I debug a situation where the compiler is not selecting the overload I expect it to?
Overload Resolution with Function Templates
How does overload resolution work when there are both function templates and non-template functions?
Overloading on const-ness of Parameters
Can I overload a function based on whether a parameter is const or non-const?
Overloading on const-ness of *this
Can I overload member functions based on the const-ness of the object they're called on?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant