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 of bp
is Base*
, name lookup will examine the scope of Base
and then find the name Base::fcn
. The fact that bp
is pointing to an object of Derived
doesn't involve in, neither the scope of Derived
and then Derived::fcn
. Dynamic dispatch happens at run-time, if Derived
has an overrided Derived::fcn()
it will be called at run-time.
If the type of bp
is Derived*
, name lookup will examine the scope of Derived
and then find the name Derived::fcn
, then name lookup stops, the scope of Base
won't be examined further more; name hiding happens.