2011-01-19 10 views
6

同じ名前の2つの関数があり、2レベルの継承で異なるシグネチャを持つベースクラスがあります。baseclassに同じ名前の2つの関数がある場合、ベース関数を見つけることができません。

struct A { 
    virtual void f(int) { } 
    virtual void f(int, int) { }; 
    virtual void f1(int) { } 
}; 

struct B: public A { }; 

struct C: public B { 
    void f(int, int) { } 
    void f1(int) { } 
}; 

int main() { 
C obj; 
obj.f1(0); 
obj.f(0,0); 

obj.f(0); // (1) cannot be found 
obj.B::f(0); // (2) works 

} 

私は(1)で正しい定義を見つけるために私のコンパイラ(GCC-4.3.2を)期待しているだろうが、私は他の手の作品で

g++  main.cpp -o main 
main.cpp: In function 'int main()': 
main.cpp:20: error: no matching function for call to 'C::f(int)' 
main.cpp:10: note: candidates are: virtual void C::f(int, int) 
distcc[2200] ERROR: compile main.cpp on localhost failed 
make: *** [main] Error 1 

(2)を取得します。

(1)を一般的に動作させるために修正する必要があるのは何ですか?

+1

+1完全な例とよく書かれたポストのための –

答えて

6

書き込みusing A::fを! void C::f(int, int)は、とにかくvoid A::f(int)を隠す。

3

「なぜ」というのは、「それがオーバーロードの仕組みだからです」という短い答えです。あなたはCでf(int)の過負荷を隠しています。長い答えはずっと長くなります。

あなたはこれを行うことによって、それをアン非表示にすることができます:あなたが名前の隠蔽の犠牲者ですC.

の定義の中

struct C: public B { 
    using A::f; 
    void f(int, int) { } 
    void f1(int) { } 
}; 
+0

あなたが答える長く教えてください。 –

+0

@honk:今は、時間が足りません。しかし、私はこれに助けを求めるでしょう。 –

+2

それほど長くはありませんが、ここに説明があります:http://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-function-in-c/888337#888337 –

4

名前が1つのスコープで再定義された場合、すべてその名前のオーバーロードが非表示になります。

しかし、usingを使用すると便利です。このように:

class A { 
    public: 
    int f(int x) { cout << "A::f 1\n"; } 
    int f(int x, int y) { cout << "A::f 2\n"; } 
}; 

class B : public A { 
    public: 
    using A::f; 
    int f(int x) { cout << "B::f 1\n"; } 
}; 

int main() 
{ 
    B b; 

    b.f(27, 34); 

    return 0; 
} 

出力は次のとおりです。

A::f 2 
関連する問題