我在 C++ 继承方面遇到问题。
我有一个类层次结构:
class A {
public:
virtual void onFoo() {}
virtual void onFoo(int i) {}
};
class B : public A {
public:
virtual void onFoo(int i) {}
};
class C : public B {
};
int main() {
C* c = new C();
c->onFoo(); //Compile error - doesn't exist
}
我的问题是:为什么不能编译?我的理解是,C 应该从 A 继承两个 onFoo 函数 - 事实上,如果你删除 B 中 onFoo 的重新定义,它就会编译 - 但 g++ 会给出一个错误,指出 C 没有 onFoo() 函数。
您遇到的问题与 C++ 中名称查找的工作方式有关。特别是,在解析成员时,编译器将查看正在访问该成员的对象的静态类型。如果在该类中找到标识符,则查找完成并且(在成员函数的情况下)重载决策开始。如果没有找到标识符,它将逐类爬行层次结构,尝试找到标识符一次一个级别.
在你的具体情况下,你有c->onFoo();
and c
属于类型C
。编译器没有看到任何声明onFoo
in C
,因此它在层次结构中继续向上。当编译器检查B
,它看到有一个声明void onFoo(int i)
在该级别,因此它停止查找,并尝试重载解析。此时,由于参数不一致,重载决策失败。
事实上,声明void onFoo(int)
出现在B
水平的影响是hiding任何基类中的其余重载,因为它将停止查找。请注意,这是不合格查找的问题,该函数仍然存在并且适用于该对象,但不会被常规查找找到(您仍然可以将其称为c->A::onFoo()
).
至于如何处理hiding,最简单的方法是使用 using 声明将函数引入作用域:
class B : A {
public:
using A::onFoo; // All A::onFoo overloads are *considered* here
void onFoo( int );
};
的效果using
这里的声明是,当B
查找类,寻找onFoo
标识符,指示编译器还考虑所有重载onFoo
在基类中,启用常规查找来查找A::onFoo()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)