C++ 为什么动态绑定可以覆盖隐藏在C++;?

C++ 为什么动态绑定可以覆盖隐藏在C++;?,c++,scope,overriding,dynamic-binding,name-hiding,C++,Scope,Overriding,Dynamic Binding,Name Hiding,我了解到内部名称隐藏外部名称(因此重载不会跨越范围),因为名称查找在类型匹配之前进行。因此,我写下面的C++代码来玩这个规则: class Base { public: virtual void fcn() {} }; class Derived : public Base { public: void fcn(std::string s) {} }; Base* bp = new Derived; bp->fcn(); delete bp; 根据隐藏规则,Derive

我了解到内部名称隐藏外部名称(因此重载不会跨越范围),因为名称查找在类型匹配之前进行。因此,我写下面的C++代码来玩这个规则:

class Base {
public:
    virtual void fcn() {}
};
class Derived : public Base {
public:
    void fcn(std::string s) {}
};

Base* bp = new Derived;
bp->fcn();
delete bp;
根据隐藏规则,
Derived::fcn(std::string)
函数应该隐藏
Base::fcn()
。但是上面的代码编译和运行都是正确的,这违反了规则。它是否意味着动态绑定可以覆盖C++中隐藏的名称?问题是,如果我将
bp
的类型更改为
Derived*
,则隐藏规则会通过发出编译错误而生效:

“派生::fcn”:函数不接受0个参数

你能帮我解释一下这种现象吗?具体地说,动态绑定可以像我假设的那样覆盖名称隐藏吗?如果是这样,如果指针指向派生类,为什么重写会失败?谢谢。

名称查找(和重载解析)在编译时进行

给定
bp->fcn
,如果
bp
的类型是
Base*
,名称查找将检查
Base
的范围,然后找到名称
Base::fcn
bp
指向
Derived
的对象这一事实既不涉及
Derived
的范围,也不涉及
Derived::fcn
的范围。动态分派发生在运行时,如果
Derived
具有重写的
Derived::fcn()
它将在运行时被调用


如果
bp
的类型是
Derived*
,则名称查找将检查
Derived
的范围,然后查找名称
Derived::fcn
,然后名称查找停止,将不再进一步检查
Base
的范围;名称隐藏发生。

名称隐藏不会使函数无法访问,只会使其名称无法访问。例如,这也是完全合法的:
Derived;d、 Base::fcn()太棒了!非常感谢你!