A member function named f in a class A will hide all other members named f in the base classes of A, regardless of return types or arguments. The following example demonstrates this:
struct A { void f() { } }; struct B : A { void f(int) { } }; int main() { B obj_B; obj_B.f(3); // obj_B.f(); }
The compiler would not allow the function call obj_B.f() because the declaration of void B::f(int) has hidden A::f().
To overload, rather than hide, a function of a base class A in a derived class B, you introduce the name of the function into the scope of B with a using declaration. The following example is the same as the previous example except for the using declaration using A::f:
struct A { void f() { } }; struct B : A { using A::f; void f(int) { } }; int main() { B obj_B; obj_B.f(3); obj_B.f(); }
Because of the using declaration in class B, the name f is overloaded with two functions. The compiler will now allow the function call obj_B.f().
You can overload virtual functions in the same way. The following example demonstrates this:
#include <iostream> using namespace std; struct A { virtual void f() { cout << "void A::f()" << endl; } virtual void f(int) { cout << "void A::f(int)" << endl; } }; struct B : A { using A::f; void f(int) { cout << "void B::f(int)" << endl; } }; int main() { B obj_B; B* pb = &obj_B; pb->f(3); pb->f(); }
The following is the output of the above example:
void B::f(int) void A::f()
Suppose that you introduce a function f from a base class A a derived class B with a using declaration, and there exists a function named B::f that has the same parameter types as A::f. Function B::f will hide, rather than conflict with, function A::f. The following example demonstrates this:
#include <iostream> using namespace std; struct A { void f() { } void f(int) { cout << "void A::f(int)" << endl; } }; struct B : A { using A::f; void f(int) { cout << "void B::f(int)" << endl; } }; int main() { B obj_B; obj_B.f(3); }
The following is the output of the above example:
void B::f(int)
Related information