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

您应该阅读访问者模式。

基本上,问题是虚函数是静态绑定的(讽刺),所以解决方案HandleInputInputInputMap.

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

注意:约定是使用纯虚方法,这样派生类就不会忘记覆盖一个。

当然,这会导致依赖性问题。幸运的是,您可以在包含InputMap.

还有更复杂的变体(搜索 Acyclic Visitor),但您现在不需要它 :)

于 2011-09-14T14:29:07.817 回答
0

函数查找和重载解析是在静态类型上执行的。所以当你说pMap->HandleInput(*this)in时StringInput::Dispatch(),总是会找到InputMap::HandleInput(Input &)重载,因为pMap它是静态类型的InputMap。然后将其动态分派给 override MyInputMap::HandleInput(Input &)

解决这个问题的一种方法是在(唯一)HandleInput()函数中添加动态调度,该函数在运行时确定参数的动态类型。

于 2011-09-14T14:22:41.020 回答