你好我当前的一个项目我想实现一个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;
};
这是我的派生输入地图
//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)
,但遗憾的是始终会调用默认处理程序。我编程这种模式错了吗?谢谢大家,我一直在盯着我的代码,但我没有看到它。
答案 0 :(得分:2)
您应该阅读Visitor模式。
基本上,问题是虚函数是静态绑定的(具有讽刺意味),因此解决方案是在HandleInput
中声明所有Input
(对于InputMap
}中的每一种类型。 / p>
class InputMap {
public:
InputMap();
virtual void HandleInput(StringInput&) = 0;
virtual void HandleInput(IntInput&) = 0;
virtual ~InputMap();
};
注意:约定是使用纯虚方法,因此没有派生类忘记覆盖它。
当然,这会导致依赖性问题。幸运的是,您可以在包含InputMap
的标头中转发声明“真实”输入类型。
有更复杂的变体(搜索非循环访客),但你现在不需要它:)
答案 1 :(得分:0)
在静态类型上执行函数查找和重载解析。因此,当您在pMap->HandleInput(*this)
中说StringInput::Dispatch()
时,总会发现InputMap::HandleInput(Input &)
重载,因为pMap
属于静态类型InputMap
。然后将其动态分派到覆盖MyInputMap::HandleInput(Input &)
。
解决此问题的一种方法是在(唯一)HandleInput()
函数中添加动态调度,该函数在运行时确定参数的动态类型。