Effective C++ item 33: Avoid Hiding Inherited Names

You probably know that local variable hides global variable name regardless of types

1
2
3
4
5
6
int x;              // global variable
void someFunc()
{
double x; // local variable
std::cin >> x; // read a new value for local x
}

Inheritance function naming share the similar mechanism.

1
2
3
4
5
6
7
8
9
10
11
class Base {
public:
virtual void mf3();
virtual void mf3(double);
...
};
class Derived: public Base {
public:
virtual void mf3(); // this hides all mf3 functions in base
...
};

Regardless of virtual, pure-virtual or non-virtual function, as soon as you define a function named mf3 in derived class, it hides all functions named mf3 in base class.

1
2
3
Derived d;
d.mf3(); // ok, calls derived class mf3 function
d.mf3(2.0); // compile error, Derived::mf3 hides Base::mf3

In public inheritance, you most likely want to inherit all public functions in base class, the way to do it to use using keyword to bring all function with certain name to the scope of derived class.

1
2
3
4
5
6
class Derived: public Base {
public:
using Base::mf3;
virtual void mf3();
...
};

This way, all mf3 functions in base class will be brought to scope in Derived.

1
2
3
Derived d;
d.mf3(); // ok, calls derived class mf3 function
d.mf3(2.0); // ok, calls base class mf3(double) function

In private inheritance, you might not want to bring all functions with certain name to scope of derived class, the way you do it is simply forward the function to cal base class version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base {
public:
virtual void mf1();
virtual void mf1(int);
};

class Derived: private Base {
public:
virtual void mf1(int a)
{ Base::mf1(int a); }
void mf1(double d)
{ ... }
...
};

Reference:
“Effective C++” Third Edition by Scott Meyers.