2011-12-29 68 views
5

爲什麼在派生類實現void operator()(int,int,int)時,下面代碼示例中基類中void operator()(int)的聲明看起來隱藏的原因讓我難堪。如何從基類foo中獲得operator()(int)的聲明,以便在派生類bar中可見?也就是說,如何修改示例以便調用operator()(int)的工作?繼承運算符()

#include <iostream> 

struct foo 
{ 
     void operator()(int) 
     { 
       std::cout << "A" << std::endl; 
     } 
}; 

struct bar : foo 
{ 
     // If this is uncommented, the code will not compile. 
     // void operator()(int, int, int) {} 
}; 

int main() 
{ 
     bar b; 
     b(1); 
     return 0; 
} 

當與編譯克++與標線取消註釋,所述錯誤消息是沿的「不匹配爲呼叫線路‘欄(INT)’...候選是無效巴::運算符()( int,int,int)...候選者需要3個參數,其中有1個參數。「

回答

6

沒錯。派生類函數隱藏基類函數而不是重載。這個修復很簡單:

struct bar : foo 
{ 
    using foo::operator(); 
    void operator()(int, int, int) {} 
}; 
+0

感謝您的回答!你能否解釋爲什麼在這種情況下使用聲明是必要的?我沒有看到如何聲明operator()(int,int,int)應該蝕刻基類中operator()(int)的聲明。不得不指定using關鍵字有點麻煩,因爲在現實世界中,我必須將它添加到每個基類中。 – 2011-12-29 16:47:59

+4

爲什麼?因爲標準是這樣說的。 「一個名稱可以通過在嵌套的聲明區域或派生類中顯式聲明同一名稱來隱藏」。另請參見:http://www2.research.att.com/~bs/bs_faq2.html#overloadderived – 2011-12-29 16:50:08

+0

實際上,重寫虛擬函數也會隱藏基類函數。當一個基類有多個同名重載的公共虛函數時,這是特別煩人的:當其中一個被重載時,所有其他的都被隱藏了!這是爲什麼標準C++庫沒有任何公共虛函數的原因之一(除了析構函數無論如何都無法重載並且在重載方面工作方面有所不同)之外。相反,公共職能委託給受保護的(他們應該真的是私人的)虛擬功能。 – 2011-12-29 16:50:30

2

請注意,operator()可能會使這個看起來更容易混淆。經典的例子可能會更像bar :: mymethod(int)和foo :: mymethod()。由於分辨率的發生,派生方法隱藏了繼承的方法。在另一個答案中解釋的使用聲明引入了foo的解決方法。