为什么动态绑定可以覆盖C ++中隐藏的名称?

时间:2019-02-20 03:11:46

标签: c++ scope override 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;

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

  

'Derived :: fcn':函数未使用0个参数

能帮我解释一下这种现象吗?具体来说,动态绑定能否覆盖我所假设的隐藏名称?如果是这样,如果指针指向派生类,为什么覆盖失败?谢谢。

1 个答案:

答案 0 :(得分:1)

名称查找(和重载解析)在编译时发生。

给出bp->fcn,如果bp的类型为Base*,则名称查找将检查Base的范围,然后找到名称Base::fcnbp指向Derived的对象这一事实既没有涉及Derived的范围,也没有涉及Derived::fcn的范围。动态调度在运行时发生,如果Derived具有覆盖的Derived::fcn(),则会在运行时被调用。

如果bp的类型为Derived*,名称查找将检查Derived的范围,然后找到名称Derived::fcn,然后名称查找停止,范围为Base将不作进一步检查;隐藏姓名。