C++派生类内部无法访问基类继承的重载方法的问题咨询
问题解答
1. 为什么Base::f(EmptyA)无法在Derived::handle中被访问?
这是C++的**名字隐藏(Name Hiding)**规则导致的:如果派生类中定义了和基类同名的函数,派生类的这个函数名会隐藏基类作用域下所有同名的重载函数,和参数列表是否匹配无关。
你在Derived类中定义了void f(DerDerEmptyA),此时在Derived的作用域内查找f标识符时,只会匹配到派生类自己的这一个f版本,基类的两个f重载完全被屏蔽,不会进入重载候选列表。编译器尝试将EmptyA类型的参数隐式转换为DerDerEmptyA(基类转派生类属于向下转型,没有自定义转换函数的情况下不允许隐式转换),因此报错。
你之前尝试直接写Base::f(ea)的方案不符合预期,是因为手动指定了Base作用域后,重载解析只会在基类范围内查找f,完全不考虑派生类的f版本,DerDerEmptyA类型的参数会向上转型为EmptyA,最终调用Base::f(EmptyA)。
2. 如何修改代码,让所有Derived::handle的调用都转发到最匹配的f方法版本?
只需要在Derived类的public作用域中添加using Base::f;声明,将基类的所有f重载引入到派生类的作用域中,重载解析时就会同时匹配基类和派生类的所有f版本,自动选择参数最匹配的调用。
修改后的Derived类代码如下:
class Derived : public Base { public: // 引入基类的所有f重载到当前作用域 using Base::f; void f(DerDerEmptyA) { std::cout << "Derived::f(DerDerEmptyA)\n"; } virtual void handle(EmptyA ea) override final { std::cout << "Derived::handle(EmptyA) - "; f(ea); } };
修改后运行程序输出为:
Derived::handle(EmptyA) - Base::f(EmptyA) Derived::handle(EmptyA) - Derived::f(DerDerEmptyA)
完全符合预期。
内容的提问来源于stack exchange,提问作者Kolay.Ne
相关产品推荐
相关产品推荐

