3

オーバーライドされた基本クラスのメソッドを再定義する必要がある理由がわかりません。

ここで、派生クラスのfoo()メソッドにコメントを付けると、コンパイルされません。

説明ありがとうございます。

class Base {
public:
    void foo() {
    }
};

class Derived: public Base {
public:
#define compile_ok
#ifdef compile_ok
    // if this method is commented, it does not compile
    void foo() {
        Base::foo();
    }
#endif
    void foo(int i) {
    }
    void test() {
        foo();
        foo(1);
    }
};

void testOverride() {
    Derived d;
    d.test();
}
4

3 に答える 3

3

あなたは基本クラス名foo(int) を隠します。次のように修正します。

class Derived: public Base {
public:
    using Base::foo;
    void foo(int i) {
    }
    void test() {
        foo();
        foo(1);
    }
};
于 2013-03-19T12:13:17.127 に答える
3

引数fooを 1 つ取る宣言を行うと、 で指定されたすべての関数が非表示になります。次のように隠し名前を持ち込むことができます。intfooBaseBase

class Derived: public Base {
public:
    using Base::foo; // Pulls foo from Base
    void foo(int i) {
    }
    void test() {
        foo();
        foo(1);
    }
};
于 2013-03-19T12:13:25.503 に答える
1

答えは、他の人がすでに言ったようfooに、派生型の が基本型の を隠しているということです。fooこれが何を意味するのかを少し拡張すると、ルックアップには一連のルールがあり、コンパイラは識別子が見つかるまでそれらのルールを適用する必要があります。名前が見つかると、より適切な一致を探し続けるのではなく、見つけたものを使用しようとします。

Derived::testtypeの内部foo()では、コンパイラは を解決する必要がありますfoo。これは何でもかまいません (型、[メンバー] 変数、[メンバー] 関数...)。そうするために、内部Derived::testで利用可能なものを探し始めますが、そこにはfoo宣言されていません。次に、検索を完全な型に広げ、Derivedメンバー関数があることを検出しますfoo。この時点で停止します*。見つからなかった場合はDerived::foo(int)、ベース、名前空間、その他の名前空間に検索を拡張し続けます...

*この特定のケースでは、識別子が関数に解決されるため、ADL が起動するときに追加の手順が実行されます (または、関数に渡された非基本型の引数があった場合は起動します)。

于 2013-03-19T12:35:24.430 に答える