2013-06-24 83 views
2

在問我的問題之前,我嘗試搜索網絡,但我不確定我需要使用哪些術語,但沒有找到解釋我的問題的方法。如果這樣的回答媒體鏈接存在,隨意只是點我吧:)根據參數的類型決議繼承的成員函數

這裏是一個小例子:

class IObject; 
class ClassA; 

class Base { 
public: void Method(IObject * object) {} 
}; 

class Derived : public Base { 
public: void Method(ClassA * objet) {} 
}; 

class IObject {}; 
class ClassA : public IObject {}; 

int main(int argc, char ** argv) { 
    IObject * object = new ClassA(); 
    Derived derived; 
    derived.Method(object); 
    delete object; 
    return 0; 
} 

這不會編譯,因爲編譯器嘗試使用派生::方法該方法的版本,即使對於給定對象存在完全有效的Base :: Method。

爲了使這個編譯(工作),我需要添加Derived中的以下內容:

class Derived : public Base { 
public: 
    // adding this line make the Base::Method visible to the compiler ?? 
    using Base::Method; 
    void Method(ClassA * object) {} 
}; 

增加這樣之後,一切都按預期工作。 我不明白的是:爲什麼?如果我將Base :: Method重命名爲Base :: BaseMethod,則可以從Derived實例調用它,而不會有任何問題。爲什麼編譯器無法根據參數的類型找到正確的方法?

+0

是的,現在我知道使用哪些術語(例如「函數隱藏」)我發現了很多答案和重複的問題:) – Citron

回答

3

這條規則在C++中被稱爲Function hiding
與基類方法具有相同名稱的派生類中的方法隱藏派生類中的基類方法。派生類的用戶只能看到派生類方法,而不考慮函數參數類型。基類方法根本不存在於派生類作用域中。所以重載分辨率不能像你期望的那樣工作。
爲了能夠訪問派生類中的Base類方法,您明確需要告訴編譯器使用using聲明將其帶入派生類作用域中。

+0

並且也非常感謝您的鏈接。根據我的理解,這個規則是爲了避免隱式投射問題而引入的。很高興知道:) – Citron

2

這稱爲成員函數隱藏:只要派生類中的函數具有與基類中具有相同名稱的函數不同的簽名,則函數的基類版本將不可見派生類和它的客戶端。 Here's這是爲什麼介紹。

+0

感謝您的回答! – Citron