2009-12-13 5 views
53

私の問題を説明するために、以下のコードを書きました。私が11行目(キーワード "using"で)コメントした場合、コンパイラはファイルをコンパイルせず、このエラーを表示します:invalid conversion from 'char' to 'const char*'SonクラスのParentクラスのメソッドvoid action(char)が見えないようです。ベースクラスのメソッドにアクセスするのに "using"キーワードを使用するのはなぜですか?

なぜコンパイラはこのように動作しますか?または私は何か間違ったことをしましたか?

class Parent 
{ 
    public: 
     virtual void action(const char how){ this->action(&how); } 
     virtual void action(const char * how) = 0; 
}; 

class Son : public Parent 
{ 
    public: 
     using Parent::action; // Why should i write this line? 
     void action(const char * how){ printf("Action: %c\n", *how); } 
}; 

int main(int argc, char** argv) 
{ 
    Son s = Son(); 
    s.action('a'); 
    return 0; 
} 
+0

私に教えてください: "const char how"でconstを削除するとどうなりますか? –

+24

'Son S = Son();'と入力する必要はありません。それはちょうど一時的なものを作成し、次にコピーコンストラクタを呼び出します。単に「Son s;」と入力してください。 –

+3

この質問はたくさんあります。[http://stackoverflow.com/questions/1835988](http://stackoverflow.com/questions/1835988)[http://stackoverflow.com/質問/ 411103](http://stackoverflow.com/questions/411103)[http://stackoverflow.com/questions/1480085](http://stackoverflow.com/questions/1480085)[http:// stackoverflow。 com/questions/1799497](http://stackoverflow.com/questions/1799497)[http://stackoverflow.com/questions/888235](http://stackoverflow.com/questions/888235)[http:// –

答えて

47

派生クラスで宣言actionC++ FAQを参照してください。 Sonオブジェクトでactionを使用する場合、コンパイラはという名前のメソッドを検索し、それを使用します。すでに一致する名前が見つかっているので、基本クラスのメソッドで検索することはできません。

このメソッドは呼び出しのパラメータと一致せず、エラーが発生します。

このトピックの詳細については、C++ FAQも参照してください。

+8

@sthそれを知っておいてください。しかし、これは、私が言うことができる、C + +の機能やバグのようなもの?これは継承という考え全体を損ねませんか? – Anubis

+0

名前の一致は名前の変更を使って行われますか?メソッドのオーバーロードはここで行われますか、名前が "action"という最初の関数です。 – tmaric

+3

@Anubis:このルールは名前検索を簡略化します。 コンパイラは、メンバ関数の名前を解決する必要がある場合(ある基底クラスでは関数のオーバーロードが発生する可能性がある)、継承ツリー全体を処理する必要があります。このルールでは、フィッティング名を含むクラスが見つかると、コンパイラは継承ツリーの残りの部分を見なくすることができます。 プログラマも同じ状況にあります。派生クラスを見ると、そこに定義されている関数が呼び出され、基本クラスに同じ名前の別の関数が含まれているかどうかを知る必要はありません。 – sth

15

驚くべきことに、これは標準的な動作です。派生クラスが、基本クラスによって定義されたメソッドと同じ名前を持つメソッドを宣言した場合、派生クラスのメソッドは基本クラスを隠します。

は、基本クラスで宣言actionを隠し

5

注意:このような状況で「使用する」を使用する必要があるため、コードが他の開発者にとって混乱を招く可能性があります。この区別を他のプログラマーに明確にするために、2つの方法のいずれかを名前変更する必要があります。

一つの可能​​性:

派生クラス任意のオーバーロードされた関数の中で再定義されている場合は、基本クラスのすべてのオーバーロードされた関数が隠されている
void action(const char how) 
{ 
    takeAction(&how); 
} 
void action(const char * how) 
{ 
    takeAction(how); 
} 
virtual void takeAction(const char * how) = 0; 
3

。 両方の機能を組み込む1つの方法は、クラスでの関数のオーバーロードを避けることです。または usingキーワードを使用できます。

関連する問題