I learnt that inner names hides outer names (so overloading does not cross scope) because name lookup goes before type matching. So I write the following C++ code to play with this rule:
class Base {
public:
virtual void fcn() {}
};
class Derived : public Base {
public:
void fcn(std::string s) {}
};
Base* bp = new Derived;
bp->fcn();
delete bp;
According to the hiding rule, the Derived::fcn(std::string) function should hide the Base::fcn(). But the above code compiles and runs correctly in defiance of the rule. Does it mean dynamic binding can override the name hiding in C++? The thing is, if I change the type of bp to Derived*, the hiding rule takes effects by uttering a compiling error:
'Derived::fcn': function does not take 0 arguments
Could you please help me explain the phenomenon? Specifically, can dynamic binding override the name hiding as I hypothesized? If so, why does the overriding fail if the pointer is pointing to the derived class? Thank you.
Name lookup (and overload resolution) happens at compile-time.
Given
bp->fcn, if the type ofbpisBase*, name lookup will examine the scope ofBaseand then find the nameBase::fcn. The fact thatbpis pointing to an object ofDeriveddoesn't involve in, neither the scope ofDerivedand thenDerived::fcn. Dynamic dispatch happens at run-time, ifDerivedhas an overridedDerived::fcn()it will be called at run-time.If the type of
bpisDerived*, name lookup will examine the scope ofDerivedand then find the nameDerived::fcn, then name lookup stops, the scope ofBasewon't be examined further more; name hiding happens.