我有以下类:
class A {
public:
virtual void f() {}
};
class B : public A{
public:
void f(int x) {}
};
如果我说:B *b = new B();
b->f();
编译器显示错误 C2660:"B::f":函数不接受 0 个参数。B 类中的函数不应该进行重载吗?因为它是虚函数,虚函数会被隐藏吗?编辑:我确实想从 A 继承 B,这展示了相同的行为。
假设你想让B
派生自A
:
f(int)
和f()
是不同的函数签名,因此是不同的函数。
您可以使用具有兼容签名的函数(即具有相同签名或返回类型“更具体”的函数)来覆盖虚函数(这称为协变)。
否则,您的派生类函数会隐藏虚函数,就像派生类声明与基类函数名称相同的函数的任何其他情况一样。您可以在类B中使用using A::f;
以取消隐藏该名称。
或者,您可以将其调用为(static_cast<A*>(b))->f();
或b->A::f();
。区别在于,如果B
实际上覆盖了f()
,则前者调用覆盖,而后者无论如何都调用A
中的函数。
virtual
时不应该发生隐藏。
但现在我明白了。谢谢 :) - OszkarA * a = new B(); a.nonVirtualFunction()
将调用A::nonVirtualFunction
,而不是B::nonVirtualFunction
。但是对于虚拟函数,它将调用B::nonVirtualFunction
,因此显然B::nonVirtualFunction
必须至少与A::nonVirtualFunction
兼容。 - ruakhClass B没有继承自A,因此不存在函数F()。你可能是想要:
class A {
public:
virtual void f() {}
};
class B : public A {
public:
void f(int x) {}
};
编辑:我错过了实际的函数隐藏。请查看Steve Jessop的答案,以获得更详细的解释。
B
并不派生自A
!+1 - wilhelmtellusing A::f;
class B : public A
virtual void f() {}
B *b = new B();
通过创建“B”的实例“b”,编译器无需使用“A”中相同名称方法的虚拟性。
如果你像这样声明了“b”
B *b = new A();
那么调用 b->f(); 将会使用虚函数解析,确实指向 A 中的方法。