2011-11-26 48 views
1
class Foo 
{ 
public: 
    int fn() 
    { 
     return 1; 
    } 
    int fn(int i) 
    { 
     return i; //2nd fn() 
    } 
}; 
class Bar:Foo 
{ 
public : 
    Foo::fn; 
}; 
int main(int argc, char** argv) 
{ 
    Bar b; 
    cout<<b.fn(2)<<endl; 
} 

使用專用的傳承隱藏一個重載的方法是可能隱藏在具體的類FN(INT)「酒吧」是有可能,而在C++

+0

請格式化您的代碼,我們是人類,而不是編譯器 – sehe

+0

您想'cout << b.fn(2)<< endl;'是編譯器錯誤嗎? – jrok

回答

1

AFAIK不,你不能「隱藏」的名字命名空間。這與名稱有關,因此包含所有可能的同名重載。

同樣,沒有辦法給unusing一個名字/名字空間。

這種現象導致了庫作者應該始終注意的頗爲鮮爲人知的ADL Pitfall


PS。在示例代碼,當然你可以只下降線說/*using*/ Foo::fn;線......但我想這是不是你的實際代碼....

1

只是讓基類privateprotected(默認情況下它是private使用class時,到目前爲止,它,是OK),不使用,但是重寫功能在派生類

class Bar: private Foo 
{ 
public: 
    int fn() {return Foo::fn();} 
}; 

這樣只會令只int fn()可見的酒吧和not int fn(int)。當然,編譯器會大聲喊出,fn不是一個虛函數,但你仍然會覆蓋它,但只要它只調用基類中的一個,它就完全相同。

+0

這不會覆蓋int fn()方法,而是通過在封閉的名稱空間中聲明一個新的標識符來隱藏它。我不認爲'這是完全相同的':虛擬的,班級佈局可能不同,不同的優化將適用,並且當子類化時類的語義將會不同。我同意,在你的樣本中,觀察到的行爲(性能除外)將是相同的。這對於OP + 1來說是一個很好的解決方法 – sehe