6

私のC++コードは次のとおりです。

#include<iostream>
using namespace std;

class A
{
    public:
        virtual void f(int i)
        {
            cout << "A's f(int)!" << endl;
        }
        void f(int i, int j)
        {
            cout << "A's f(int, int)!" << endl;
        }
};

class B : public A
{
    public:
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};

int main()
{
    B b;
    b.f(1,2);
    return 0;
}

コンパイル中に私は得る:

g++ -std=c++11 file.cpp 
file.cpp: In function ‘int main()’:
file.cpp:29:9: error: no matching function for call to ‘B::f(int, int)’
file.cpp:29:9: note: candidate is:
file.cpp:20:16: note: virtual void B::f(int)
file.cpp:20:16: note:   candidate expects 1 argument, 2 provided

Bのf(int)の後にオーバーライドを使用しようとすると、同じエラーが発生しました。

C ++で1つのメソッドのみをオーバーライドすることは可能ですか?私は自分のマシンでコンパイルされるコード例を探していましたが、overrideまだ見つかりませんでした。

4

5 に答える 5

11

f()問題は、クラス内の仮想関数が同じ名前のの非仮想オーバーロードを非B 表示にすることです。 宣言をA使用して、それをスコープに含めることができます。using

class B : public A
{
    public:
        using A::f;
    //  ^^^^^^^^^^^

        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};
于 2013-03-16T15:28:23.353 に答える
6

メソッド名として「f」という名前をオーバーライドしています。したがって、過負荷もオーバーライドされます。

usingキーワードを使用して、コンパイラに基本クラスも確認するように指示することができます。

class B : public A
{
    public:
        using A::f;
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};
于 2013-03-16T15:30:19.077 に答える
5

あなたはC++での名前検索のしくみに悩まされています。コンパイラーは、名前が一致する項目が少なくとも1つあるスコープが見つかるまで、連続するスコープを検索します。

そのアイテムが関数であると仮定すると、そのスコープで見つかったその名前の関数間でオーバーロード解決を実行します。これらのいずれも機能しない場合は、より適切なものを見つけるためにさらに多くのスコープを検索し続けることはありません。

ただし、この場合は、親のクラスを検索するように取得できます。

class B : public A
{
    public:
        using A::f;
        virtual void f(int i)
        {
            cout << "B's f(int)!" << endl;
        }
};

一見すると、usingステートメントがあいまいさを生み出す可能性があるように見えるかもしれません。たとえば、のスコープ(および)に2つの関数が表示されるようにusing A::f;なりました。C ++にもこれをカバーするいくつかのルールがあるため、(たとえば)を(インプレースで)追加しても、あいまいさは生じません。期待どおりに呼び出されます。 f(int)BA::f(int)B::f(int)b.f(3);mainusing A::f;b::f(int)

于 2013-03-16T15:32:05.547 に答える
1

f派生クラスで定義された関数は、基本クラスの関数を名前で非表示にしfます。
派生クラスのスコープに非表示の関数を含めるには、次を追加する必要があります。

using A::f;

基本クラス定義に。

良い読み物:

警告:Derived :: f(char)はBase :: f(double)を非表示にしますか?

于 2013-03-16T15:27:41.853 に答える
0

はい、クラスの1つのメソッドだけをオーバーライドして、仮想化することができます。非仮想は、継承されたクラスで宣言されたときにシャドウイングされます。

于 2013-03-16T15:29:18.710 に答える