我了解到内部名称隐藏外部名称(因此重载不会超出范围),因为名称查找先于类型匹配。因此,我编写了以下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个参数
能帮我解释一下这种现象吗?具体来说,动态绑定能否覆盖我所假设的隐藏名称?如果是这样,如果指针指向派生类,为什么覆盖失败?谢谢。
答案 0 :(得分:1)
名称查找(和重载解析)在编译时发生。
给出bp->fcn
,如果bp
的类型为Base*
,则名称查找将检查Base
的范围,然后找到名称Base::fcn
。 bp
指向Derived
的对象这一事实既没有涉及Derived
的范围,也没有涉及Derived::fcn
的范围。动态调度在运行时发生,如果Derived
具有覆盖的Derived::fcn()
,则会在运行时被调用。
如果bp
的类型为Derived*
,名称查找将检查Derived
的范围,然后找到名称Derived::fcn
,然后名称查找停止,范围为Base
将不作进一步检查;隐藏姓名。