2011-12-29 7 views
5

派生クラスでvoid operator()(int,int,int)を実装すると、下のコードサンプルの基底クラスのvoid operator()(int)の宣言が一見隠されているように見えません。ベースクラスfooのoperator()(int)の宣言を派生クラスbarに表示させるにはどうすればよいですか?つまり、operator()(int)の呼び出しが機能するようにサンプルを変更するにはどうすればよいですか?operator()の継承

#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、int))の宣言が基本クラスのoperator()(int)の宣言をどのようにして実行するのか分かりません。 usingキーワードを指定しなければならないのは、実際のシナリオではすべての基本クラスにこれを追加する必要があるため、少し面倒です。 –

+4

なぜですか?スタンダードはそう言いますから。 "名前は、ネストされた宣言的な領域または派生クラスの同じ名前の明示的な宣言によって隠すことができます。"参照:http://www2.research.att.com/~bs/bs_faq2.html#overloadderived –

+0

実際には、仮想関数をオーバーライドすると基本クラスの関数も隠されます。これは、基本クラスが同じ名前のオーバーロードである複数のパブリック仮想関数を持っている場合に特に厄介です:それらのうちの1つだけをオーバーライドすると、他のすべてが隠されます!これは、標準のC++ライブラリにパブリック仮想関数がない理由の1つです(とにかくオーバーロードできず、とにかくオーバーライドに関して多少異なるデストラクタを除いて)。代わりに、public関数は保護された(実際にはプライベートであるべき)仮想関数に委譲します。 –

2

この見た目は、これよりも混乱する可能性があります。古典的な例はおそらくbar :: mymethod(int)とfoo :: mymethod()のようなものでしょう。派生したメソッドは、解決方法のために継承されたメソッドを隠します。別の答えで説明されている使用宣言は、fooの解決方法をもたらします。