As we’ve seen, functions declared in an inner scope do not overload functions declared in an outer scope (§6.4.1, p. 234). As a result, functions defined in a derived class do not overload members defined in its base class(es). As in any other scope, if a member in a derived class (i.e., in an inner scope) has the same name as a base-class member (i.e., a name defined in an outer scope), then the derived member hides the base-class member within the scope of the derived class. The base member is hidden even if the functions have different parameter lists:
struct Base {
int memfcn();
};
struct Derived : Base {
int memfcn(int); // hides memfcn in the base
};
Derived d; Base b;
b.memfcn(); // calls Base::memfcn
d.memfcn(10); // calls Derived::memfcn
d.memfcn(); // error: memfcn with no arguments is hidden
d.Base::memfcn(); // ok: calls Base::memfcn
The declaration of memfcn
in Derived
hides the declaration of memfcn
in Base
. Not surprisingly, the first call through b
, which is a Base
object, calls the version in the base class. Similarly, the second call (through d
) calls the one from Derived
. What can be surprising is that the third call, d.memfcn()
, is illegal.
To resolve this call, the compiler looks for the name memfcn
in Derived
. That class defines a member named memfcn
and the search stops. Once the name is found, the compiler looks no further. The version of memfcn
in Derived
expects an int
argument. This call provides no such argument; it is in error.