2010-01-29 73 views
21

在C++中,即使其原型(参数'count,type和constness)不同,基类的成员函数是否会被其派生类函数重名为?我猜这是一个愚蠢的问题,因为很多网站都说函数原型应该与发生的相同;但为什么不能编译下面的代码?我相信这是一个非常简单的继承案例。C++继承和函数重写

#include <iostream> 
using std::cout; 
using std::endl; 

class A {}; 
class B {}; 

class X 
{ 
public: 
    void spray(A&) 
    { 
     cout << "Class A" << endl; 
    } 
}; 

class Y : public X 
{ 
public: 
    void spray(B&) 
    { 
     cout << "Class B" << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    B b; 
    Y y; 

    y.spray(a); 
    y.spray(b); 

    return 0; 
} 

GCC抛出

error: no matching function for call to `Y::spray(A&)' 
note: candidates are: void Y::spray(B&) 
+0

得到了关于同一问题的C++常见问题解答,如果有人需要它,请详细解释:) http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq- 23.9 – legends2k 2010-01-29 11:40:26

+1

说签名应该是相同的,这有点危险。签名是名称修改和链接的基础。两个不同班级的成员总是拥有不同的签名,即使这两个成员优先于另一个班级。我认为,即使说更长的时间,最好说“相同的参数类型,名称和常量”。 – 2010-01-29 11:44:37

+0

@litb:谢谢澄清!我想'原型'是在这里的恰当的词,我已经改变了它的问题:) – legends2k 2010-01-29 12:35:24

回答

28

用来形容这是“隐藏”,而不是“覆盖”一词。默认情况下,派生类的成员将使相同名称的基类成员不可访问,无论它们是否具有相同的签名。如果您想访问基类成员,可以使用using声明将它们拉入派生类。在这种情况下,添加以下class Y

using X::spray; 
+0

感谢您的解释,说得很清楚。它在我在这里添加using指令时起作用。但是,当我改变喷雾特征在X中喷射(int)并在Y中喷射(浮动)并调用y.spray(1)时;和y.spray(1.0f);它没有使用指令。怎么来的? – legends2k 2010-01-29 11:20:18

+2

对不起,我的坏,它仍然只是看到Y的喷雾(浮),当我做y.spray(1);它类型将int转换为隐式浮动。 – legends2k 2010-01-29 11:26:56

+2

这是一个值得自己的特殊问题,用大量的搜索粉制作的答案,以便人们可以更好地找到答案。 – Wug 2013-07-16 22:50:58

10

这就是所谓的 '隐藏':Y::spray隐藏X::spray。 添加使用指令:

class Y : public X 
{ 
public: 
    using X::spray; 
    // ... 
}; 
5

类是范围和类的作用域嵌套在其父。您与其他嵌套范围(名称空间,块)具有完全相同的行为。

当名称查找搜索名称的定义时,它会查看当前名称空间,然后查找名称空间等等,直到找到一个定义为止;然后停止搜索(这没有考虑到参数相关名称查找引入的复杂性 - 允许使用在其参数的名称空间中定义的函数的规则的一部分)。

+0

感谢您解释hinding背后的根本原因;它真的说为什么我首先得到了这个错误,以及为什么使用指令解决了它。 – legends2k 2010-01-29 12:44:27