2012-09-06 33 views
0

我有一個關於繼承和模板方法的問題。假設我有這兩類模板化方法的遺傳

class Base 
{ 
public: 
    template<typename T> 
    void print(const T& s) {std::cout << "Base (templated) prints " << s << "\n";} 
    virtual void print(int i) {std::cout << "Base prints " << i << "\n";} 
}; 

class Derived : public Base 
{ 
public: 
    void print(int i) {std::cout << "Derived prints " << i << "\n";} 
} 

int main() 
{ 
    Derived d; 
    d.print(3);  // works fine 
    std::string s = "hi"; 
    d.print(s); // does not compile 
    return 0; 
} 

編譯器告訴我'不匹配函數調用「派生::打印(的std :: string &)」」。 但是派生,從Base繼承,還應該允許調用模板方法print(..),否?

如果我沒有在派生類中定義一個方法「print」,那麼事情也很奇怪,那麼一切正常,編譯器會調用基類模板方法。

事情做工精細也是,如果我還定義模板方法在派生類中,它調用基類之一,但似乎並不正確,我...

感謝您的幫助。

+0

好吧,我編輯了這個問題,原因是有一些我特別忽略了。我試圖簡化這個問題,但我可能忽略了重要的細節(如虛函數)。 – bartgol

回答

2

在派生類中聲明一個函數會隱藏基類中具有相同名稱的任何函數。您可以使用使用聲明來取消隱藏它們:

class Derived : public Base 
{ 
public: 
    // Add this 
    using Base::print; 

    void print(int i) {std::cout << "Derived prints " << i << "\n";} 
} 
+0

謝謝!出於某種原因,我認爲由於其中一個是模板化的,另一個不是,所以他們不會被認爲是相同的。此外,因爲基類有一個方法(不是模板),完全匹配作爲簽名派生的。所以我雖然派生一個只隱藏那一個。 (我編輯的問題也包括非模板版本的基礎類)。 – bartgol

1

這是一個標準的基本名稱hide,並且與基類函數是一個模板的事實完全沒有任何關係。它可能是耶穌的第二次到來,編譯器仍然會隱藏它。這是正常的行爲,實現了嘗試並保護派生類免受基類中意外更改的影響。

+0

謝謝!出於某種原因,我雖然無法隱藏模板方法...我只是認爲它是不同的... – bartgol