2010-11-10 60 views
20

我有以下类别:为什么虚拟功能会隐藏?

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显示了相同的行为。

+9

也许你想得出''从A' B' “这是使用using声明轻松完成”? – 2010-11-10 16:17:48

回答

35

假设你打算从BA得出:

f(int)f()是不同的签名,因此不同的功能。

您可以覆盖具有兼容签名的函数的虚拟函数,这意味着要么是相同的签名,要么是返回类型是“更具体”(这是协方差)的函数。就像其他派生类声明具有与基类函数同名的函数的情况一样,派生类函数隐藏虚函数。您可以将using A::f;放在B类中以取消隐藏名称

或者,您可以将其称为(static_cast<A*>(b))->f();b->A::f();。不同的是,如果B实际上确实覆盖了f(),则前者调用覆盖,而后者则调用A中的函数。

+0

澄清它!我不知道为什么我认为使用'虚拟'时不应该发生隐藏。 但我现在看到它。谢谢:) – Oszkar 2010-11-11 07:15:06

+0

为什么我们无法隐藏不同返回类型的虚函数?即使非虚函数允许不同的返回类型。 – UnKnown 2016-03-12 13:14:34

+0

@UnKnown:使用*非*虚函数,函数是完全独立的; 'A * a = new B(); a.nonVirtualFunction()'将调用'A :: nonVirtualFunction',而不是'B :: nonVirtualFunction'。但是使用* virtual *函数,它会调用'B :: nonVirtualFunction',所以显然'B :: nonVirtualFunction'必须至少与'A :: nonVirtualFunction'最低限度兼容。 – ruakh 2016-12-26 17:32:53

7

B类不从A派生,所以没有函数F()存在。你大概的意思是:

class A { 
public: 
    virtual void f() {} 
}; 


class B : public A { 
public: 
    void f(int x) {} 
}; 

编辑:我错过了实际功能隐藏。请参阅Steve Jessop的答案以获得更全面的解释。

+0

虽然看上去很好,但并不能解决问题(请参阅Steve Jessops的回答)。 – 2010-11-10 16:19:16

+0

像@SteveJessop这样的LOL我跳上了签名问题,甚至没有注意到'B'不是来自'A'! +1 – wilhelmtell 2010-11-10 16:19:20

+0

@wilhelmtell:没错,我没有注意到遗漏的遗传,直到罗德指出它。 – 2010-11-10 16:22:43

2

B不从A派生,正确的声明是:

class B : public A 
+0

是的,我忘了,谢谢。 – Oszkar 2010-11-11 07:12:41

2

当编译器解析符号的方法不止一种,它必须选择哪一个具有优先权,除非代码告诉它,否则。你期望的是重载优先于重载。 (一遍又一遍,结束,aaaaack!对不起,被'淹没了')。

此示例使B继承了子类提供重载版本的虚拟方法。重载是使用相同方法名称但不同签名的同一类中的方法。由于B是A的一个子类,它重写了f(),这意味着它不能同时也是一个超载。这就是它被隐藏的原因。

对于A类,声明方法

virtual void f() {} 

虚拟意味着方法使用一组特定的不与你B的声明一致的规则来解决。

B *b = new B(); 

通过创建“B”为“B”的一个实例,编译器没有必要使用相同的名称的方法的虚拟性质在“A”。

如果你已经宣布 'B' 这样

B *b = new A(); 

则呼叫B-> F();确实会通过使用虚拟分辨率来引用A中的方法。

+0

我忘了写这种方式。我现在纠正了它。 – Oszkar 2010-11-11 07:13:02

4

分别是和是。如果你想超载行为,你需要说

using A::f; 

在B.

+0

'B'不是从'A'派生的 – 2010-11-10 16:22:57

+1

确实,我错过了那个:)但是,如果是这样,那就是你需要做的。 – 2010-11-10 19:45:15

+0

是的,我的意思是推导它。谢谢! – Oszkar 2010-11-11 07:12:10