web-dev-qa-db-ja.com

基本クラスメソッドにアクセスするために「using」キーワードを使用する必要があるのはなぜですか?

私の問題を説明するために、以下のコードを書きました。 11行目に(キーワード "using"を使用して)コメントすると、コンパイラはファイルをコンパイルせず、次のエラーを表示します:_invalid conversion from 'char' to 'const char*'_。 ParentクラスにSonクラスのvoid action(char)メソッドが表示されていないようです。

コンパイラがこのように動作するのはなぜですか?または、何か間違ったことをしたことがありますか?

_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;
}
_
64
Julien Vaslet

派生クラスで宣言されたactionは、基本クラスで宣言されたactionを隠します。 actionオブジェクトでSonを使用すると、コンパイラはSonで宣言されたメソッドを検索し、actionと呼ばれるメソッドを見つけて使用します。一致する名前が既に見つかっているため、基本クラスのメソッドの検索は続行されません。

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

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

55
sth

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

C++ FAQ を参照してください

16
Amnon

注意点:この状況で「使用」を使用する必要があるのは、コードが他の開発者を混乱させる可能性があるという赤い旗です(結局、コンパイラを混乱させます!)。他のプログラマーに区別を明確にするために、2つのメソッドのいずれかを名前変更する必要があります。

1つの可能性:

void action( const char how )
{ 
  takeAction( &how ); 
}
void action( const char * how )
{
  takeAction(how);
}
virtual void takeAction(const char * how) = 0;
6
Dale Wilson

派生クラスでオーバーロードされた関数が再定義された場合、基本クラスのすべてのオーバーロードされた関数は非表示になります。両方の機能を含める1つの方法は、クラスでの関数のオーバーロードを回避することです。またはusingキーワードを使用できます。

5
Bhupesh Pant