|
||||
|
Section 23:
|
[23.9] What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?
It means you're going to die. Here's the mess you're in: if Base declares a member function f(double x), and Derived declares a member function f(char c) (same name but different parameter types and/or constness), then the Base f(double x) is "hidden" rather than "overloaded" or "overridden" (even if the Base f(double x) is virtual).
class Base {
public:
void f(double x); ← doesn't matter whether or not this is virtual
};
class Derived : public Base {
public:
void f(char c); ← doesn't matter whether or not this is virtual
};
int main()
{
Derived* d = new Derived();
Base* b = d;
b->f(65.3); ← okay: passes 65.3 to f(double x)
d->f(65.3); ← bizarre: converts 65.3 to a char ('A' if ASCII) and passes it to f(char c); does NOT call f(double x)!!
delete d;
return 0;
}
Here's how you get out of the mess: Derived must have a using
declaration of the hidden member function. For example,
class Base {
public:
void f(double x);
};
class Derived : public Base {
public:
using Base::f; ← This un-hides Base::f(double x)
void f(char c);
};
If the using syntax isn't supported by your compiler, redefine the
hidden Base member function(s), even if they are
non-virtual. Normally this re-definition merely calls the hidden
Base member function using the :: syntax. E.g.,
class Derived : public Base {
public:
void f(double x) { Base::f(x); } ← The redefinition merely calls Base::f(double x)
void f(char c);
};
Note: the hiding problem also occurs if class Base declares a method
f(char).
Note: warnings are not part of the standard, so your compiler may or may not give the above warning. Note: nothing gets hidden when you have a base-pointer. Think about it: what a derived class does or does not do is irrelevant when the compiler is dealing with a base-pointer. The compiler might not even know that the particular derived class exists. Even if it knows of the existence of some particular derived class, it cannot assume that a specific base-pointer necessarily points at an object of that particular derived class. Hiding takes place when you have a derived pointer, not when you have a base pointer. |
|||