2010-01-29 77 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