C++虚函数被隐藏

2024-01-07

我在 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(使用前将#替换为@)

C++虚函数被隐藏 的相关文章

随机推荐