|
||||
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. |