1

我了解到内部名称隐藏了外部名称(因此重载不会跨越范围),因为名称查找在类型匹配之前进行。所以我写了下面的 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++ 中的名称?问题是,如果我将类型更改为bpto Derived*,隐藏规则会通过发出编译错误来生效:

'Derived::fcn':函数不接受 0 个参数

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

4

1 回答 1

1

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

给定bp->fcn,如果类型bpBase*,名称查找将检查范围,Base然后找到名称Base::fcnbp指向对象的事实Derived不涉及,也不涉及Derivedand的范围Derived::fcn。动态调度发生在运行时,如果Derived有一个覆盖Derived::fcn(),它将在运行时调用。

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

于 2019-02-20T03:24:37.173 回答