虚函数被隐藏
C++ Virtual function being hidden
我遇到一个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();
和c
类型为C
。编译器在C
中没有看到任何onFoo
的声明,所以它在层次结构中继续向上。当编译器检查B
时,它看到在该级别有一个void onFoo(int i)
的声明,因此它停止查找,并尝试重载解析。此时,由于参数不一致,重载解析失败。
在B
级别上存在void onFoo(int)
声明的事实具有隐藏任何基类中的其余重载的效果,因为它将停止查找。请注意,这是一个非限定查找的问题,函数仍然存在并适用于对象,但不会被常规查找找到(您仍然可以将其称为c->A::onFoo()
)。
class B : A {
public:
using A::onFoo; // All A::onFoo overloads are *considered* here
void onFoo( int );
};
这里using
声明的作用是,当查找B
类时,在搜索onFoo
标识符时,指示编译器也考虑基类中onFoo
的所有重载,从而启用常规查找以查找A::onFoo()
。
如果您希望基类成员重载派生类成员,您需要使用using
:
struct A
{
virtual void onFoo() {}
virtual void onFoo(int i) {}
};
struct B : A
{
using A::onFoo;
virtual void onFoo(int i) {}
};
struct C : B
{
};
int main()
{
C* c = new C();
c->onFoo();
}
这是名称隐藏,基本上只有声明的覆盖存在于B中,其他的重载隐藏在A中
类A和B的方法应该是公共的。而且在每个类声明的末尾都缺少分号。
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
}
您在A类和b类的方法之前忘记了public:
修饰符。因此方法onFoo是私有的,因此在这些类之外的任何地方都不可见。
我猜你错过了在class B
中添加这个:
struct B : A
{
using A::onFoo;
virtual void onFoo(int i) {}
void onFoo() {} //This line missing in your code.
};
现在编译了!
- 参数包构造函数在类模板中隐藏用户定义的转换
- 名称隐藏对静态函数继承的实例使用
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 函数隐藏和重载之间的区别
- c++ 内联友元函数是否会导致命名空间之间的名称隐藏?
- 使用函数参数隐藏成员函数
- 函数的隐藏/锚定参数?
- 调用虚函数的逻辑不清楚(或者是方法隐藏?
- 隐藏私有过载的虚拟函数?
- static_assert:派生"must"中的某个函数隐藏了Base的类函数
- 在继承的类构造函数中使用隐藏成员
- C 如何使用隐藏的默认构造函数初始化成员
- 函数隐藏和使用C 中的函数
- 基的私有虚函数由派生的私有虚函数隐藏
- 如何模拟在c++中重写父函数(而不是隐藏)
- 对子级隐藏函数
- 访问具有不同签名的基类中的隐藏函数
- 隐藏函数的实例化
- 我如何使用 no除非我从继承列表中选择特定的隐藏函数
- 如何在发布源代码之前隐藏c++函数定义