c++scopeoverridingdynamic-bindingname-hiding

Why can dynamic binding override name hiding in C++?


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.


Solution

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