78

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

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

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;
}
4

5 に答える 5

66

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

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

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

于 2009-12-13T15:45:22.200 に答える
20

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

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

于 2009-12-13T15:44:12.623 に答える
6

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

1つの可能性:

void action( const char how )
{ 
  takeAction( &how ); 
}
void action( const char * how )
{
  takeAction(how);
}
virtual void takeAction(const char * how) = 0;
于 2013-01-23T22:22:39.483 に答える
6

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

于 2014-10-07T10:37:57.093 に答える
0

を使用することによりusing、基本クラスで宣言された名前が派生クラスの名前空間に導入されます。

次に、派生クラスで関数のセットを宣言すると、コンパイラーによって、暗黙のthisポインターの型によって、基本クラスで同じパラメーター型を持つ関数と区別されます。

過負荷の解決中、派生クラスへのポインターが基本クラスへのポインターに変換されるときに発生する、クラス型変換を必要とする引数の優先度は最も低くなります。

したがって、一見同一のパラメータリストを持つ2つの関数を区別でき、派生型のオブジェクトからそれらを呼び出す場合、ローカルで宣言された関数の方が(正確ではないにしても)より適切に一致します。

私は初心者です。誤解を指摘してください。

于 2021-08-24T08:21:06.163 に答える