为何C++子类对象调用父类重载方法需显式指定父类前缀?
子类调用父类函数的编译差异解析
先贴示例代码:
#include <iostream> using namespace std; class A{ public: A() = default; virtual void foo() = 0; bool foo(int x) { cout<<"A::foo(int x)\n"; return true; } bool func(int x) { cout<<"A::func(int x)\n"; return true; } }; class B: public A { public: B() = default; void foo() { cout<<"B::foo()\n"; } }; int main() { B b; b.func(0); //b.foo(0); //it's not compiled b.A::foo(0); return 0; }
编译差异的原因
这是C++的**名字遮蔽(Name Hiding)**规则导致的:
- 对于
func函数:子类B中没有定义任何名为func的函数,编译器处理b.func(0)时,会沿着继承链向上查找,最终在父类A中找到匹配int参数的bool func(int x),因此能正常编译运行。 - 对于
foo函数:父类A有两个重载版本——virtual void foo() = 0和bool foo(int x),但子类B定义了自己的void foo()。此时子类的foo会遮蔽父类中所有同名的重载函数。调用b.foo(0)时,编译器只会在B的作用域内查找foo,仅找到无参数的void foo(),与传入的int参数不匹配,因此编译报错。而显式写b.A::foo(0)时,直接指定去父类A的作用域查找,就能找到带int参数的重载版本,所以可以正常运行。
内容的提问来源于stack exchange,提问作者Shoam
相关产品推荐
相关产品推荐

