2

これは、私が以前に尋ねた問題のパート 2 です: C++ でポリモーフィック メンバーのオーバーロードを行うことは可能ですか?

Wiki の例を使用して、この例を作成しました。 http://en.wikipedia.org/wiki/Double_dispatch

私の問題は、コンパイルされたコードが vtable を検索せず、継承されたクラスの代わりに常にベースを使用することです。これが私のコードです:

#include <iostream>

class xEntity;
class xVehicle;

class xMapObject
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "MapObject Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "MapObject Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "MapObject Bump Vehicle\n"; };
};

class xEntity : public xMapObject
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "Entity Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "Entity Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "Entity Bump Vehicle\n"; };
};

class xVehicle : public xEntity
{
  public:
    virtual void Bump(xMapObject&) { std::cout << "Vehicle Bump MapObject\n"; };
    virtual void Bump(xEntity&) { std::cout << "Vehicle Bump Entity\n"; };
    virtual void Bump(xVehicle&) { std::cout << "Vehicle Bump Vehicle\n"; };
};

int main(int argv, char **argc)
{
    xEntity Entity;
    xVehicle Vechile;

    xMapObject &EntityRef = Entity;
    xMapObject &VehicleRef = Vechile;

    VehicleRef.Bump(EntityRef);

    return 0;
}

ただし、出力は常に次のようになります。

Vehicle Bump MapObject

この謎についての助けは大歓迎です。

4

3 に答える 3

6

ダブルディスパッチではなく、シングルディスパッチのみを行いました。アイデアは、でxVehicle、あなたダブルディスパッチであるxMapObject&と呼ぶだろうということです。ref.bump(*this);

于 2011-01-12T16:56:53.453 に答える
1

vtable を使用しています。それが呼んでいる理由xVechicle::Bump()です!vtable は引数では使用されません。これは意味がありません (少なくとも C++ では)。

典型的な解決策は、例えばBump(xMapObject& obj)callを持つことobj.Bump(*this);です。

于 2011-01-12T17:00:08.677 に答える
1

基本クラスのパラメーターとして派生クラスを使用しているため、xEntity::Bump(xVehicle&) の設計が不適切です。

少なくとも契約が変更された場合は、基本のBumpメソッドを再定義する必要はありません。

問題は、派生クラスを基本クラスに変換するxMapRef変数を作成していることです。

適切なメソッドを呼び出したい場合は、派生クラス オブジェクトで呼び出すだけです

于 2011-01-12T17:41:03.640 に答える