1

こんにちは、私の現在のプロジェクトの1つで、InputMapを実装したいと思います。だから私は抽象的な入力を持っています

//Input.h
namespace INPUT {
class InputMap;
class Input {
public:
    Input();
    virtual ~Input();
    virtual void Dispatch( InputMap * pMap ) = 0;
};
}

およびInputMap

//InputMap.h
namespace INPUT {
class InputMap {
public:
    InputMap();
    virtual void HandleInput( INPUT::Input & anInput ) {
    }
    virtual ~InputMap();
};
}

これまでのところ良好です-ここには機能がありません。ここで、抽象入力クラスから最初の実際の入力を導出します。

//StringInput.h
#include "Input.h"
#include "InputMap.h"
#include <string>

class StringInput : INPUT::Input {
public:
    StringInput();
    virtual ~StringInput();
    void Dispatch(INPUT::InputMap * pMap)
    {
        pMap->HandleInput( *this );
    }
    void SetMessage(std::string message);
    std::string GetMessage() const;
private:
     std::string m_message;
};

これが私の派生したInputMapです

//MyInputMap.h
#include "InputMap.h"
#include "StringInput.h"

class MyInputMap: public INPUT::InputMap {
public:
    MyInputMap();
    void HandleInput( StringInput & anInput );
    void HandleInput( INPUT::Input & anInput );
    virtual ~MyInputMap();
};

そしてここにテストがあります:

//main.cpp
MyInputMap map;
StringInput input;
input.SetMessage("Test");
input.Dispatch(&map);

input.Dispatch(&map)もちろん、それがを呼び出すことを期待していますmap.HandleInput(StringInput input)が、残念ながら、デフォルトのハンドラーは常に呼び出されます。このパターンを間違ってプログラムしましたか?みんなありがとう、私は自分のコードをずっと見つめてきました、しかし私はそれを見ません。

4

2 に答える 2

2

ビジターパターンについて読む必要があります。

基本的に、問題は仮想関数が静的にバインドされている(ironic)ことです。したがって、解決策は、ですべてHandleInput(のすべてのタイプに対してInput)を宣言することInputMapです。

class InputMap {
public:
    InputMap();
    virtual void HandleInput(StringInput&) = 0;
    virtual void HandleInput(IntInput&) = 0;
    virtual ~InputMap();
};

注:慣例では、純粋仮想メソッドを使用するため、派生クラスがオーバーライドを忘れることはありません。

もちろん、これは依存関係の問題を引き起こします。幸い、を含むヘッダーで「実際の」入力型を前方宣言できますInputMap

より複雑なバリエーションがあります(AcyclicVisitorを検索してください)が、今は必要ありません:)

于 2011-09-14T14:29:07.817 に答える
0

関数のルックアップと過負荷の解決は、静的タイプで実行されます。したがって、で言うとpMap->HandleInput(*this)、静的タイプであるためStringInput::Dispatch()、これは常にInputMap::HandleInput(Input &)オーバーロードを検出します。次に、これはオーバーライドに動的にディスパッチされます。pMapInputMapMyInputMap::HandleInput(Input &)

HandleInput()これを克服する1つの方法は、実行時に引数の動的タイプを決定する(一意の)関数内に動的ディスパッチを追加することです。

于 2011-09-14T14:22:41.020 に答える