2

基本クラスの別のメソッドによって使用される基本クラスのメソッドをオーバーライドしようとしています。ただし、派生クラスが基本クラスの using-method を呼び出すと、派生した used-method は実行されず、代わりに基本クラスの used-method が呼び出されます。次に例を示します。

#include <iostream>
using namespace std;
class Base {
public:
    Base() {}
    virtual ~Base() {}
    void printLeft() { cout << this->getLeft(); }
    int getLeft() { return 0; }
};

class Derived: public Base {
public:
    Derived() {}
    virtual ~Derived() {}
    int getLeft() { return 1; }
};
int main(int argc, char *argv[]) {
    Derived d = Derived();
    d.printLeft();
}

派生オブジェクトのメソッドではなく、のメソッドが使用されたことを示すmain()printを実行しています。0BasegetLeft()

Derived のインスタンスから呼び出されたときに呼び出されるDerived::getLeft()ように、このコードを変更するにはどうすればよいですか?

4

2 に答える 2

6

getLeft仮想にするだけです:

class Base {
public:
    Base() {}
    virtual ~Base() {}
    void printLeft() { cout << this->getLeft(); }
    virtual int getLeft() { return 0; }
};

C++ のデフォルトでは、メンバー関数は仮想ではありません。つまり、サブクラスでそれらをオーバーライドすることはできません。

于 2012-05-15T16:02:33.503 に答える
1

非仮想関数の場合、オブジェクトの静的タイプを使用して、呼び出されるクラスのメソッドを決定します。

あなたの場合、あなたはgetLeft()から呼び出していBase::printLeft()ます。のタイプthisBase*、であるため、呼び出される関数はになりますBase::getLeft()

これを回避する方法は、virtualキーワードを使用することです。その場合、仮想関数テーブルを使用してgetLeft()、呼び出すバージョンを決定します。この場合は、Derived.

との両方virtualの宣言の前に追加することで、この動作をトリガーできます。printLeftBaseDerived

于 2012-05-15T16:13:51.483 に答える