我正在构建Boost状态机。我的州有一个指向自己的后端(fsm
)的指针来处理事件。我的状态机的所有事件都是MySatetMachineEvent
类的子级(例如EventChild
这样的子级)。仅为像EventChild
中的MySTateMachineEvent
之类的孩子定义状态转换。
为了清理代码,我想创建一个函数processEvent(MySatetMachineEvent event)
来处理所有可能的事件。然后,此类应使用传递的事件来调用process_event()
函数。
例如:
processEvent(MyStateMachineEvent event)
{
fsm.process_event(event);
}
processEvent(EventCild());
应该打电话给
fsm.process_event(EventChild());
创建这样的函数会导致错误,导致fsm.process_event()
的实例MyStateMachineEvent
被调用。如上所述,没有为这种情况定义状态转换。
显然,这阻碍了我的状态机正常工作。
所以我的问题是,是否有一种方法可以将EventChild
的任何MyStateMachineEvent
或其他子元素传递给我的processEvent(MySTateMachineEvent event)
函数,而不将传递的对象强制转换为MyStateMachineEvent
。 / p>
我知道可以覆盖我的函数的解决方案
processEvent(EventChild event) {
fsm.process_event(event);
}
在我的情况下,这可能会导致可能的功能(其中的代码行完全相同),因此我正在寻找一种更干净,更精美的解决方案。
答案 0 :(得分:3)
您可以使用功能模板:
template <typename Event>
void processEvent(Event event)
{
fsm.process_event(event);
}
每个实例化都将保留传入的event
参数的确切类型。
答案 1 :(得分:0)
尽管我喜欢Vittorio Romeo的template approach,但如果您喜欢,可能不适合。 G。具有某种可容纳任意事件的事件队列。那么,多态方法可能更合适:
class MyStateMachineEvent
{
public:
virtual ~MyStateMachineEvent() { }
virtual void doOrGetSomething() = 0;
};
class EventChild : public MyStateMachineEvent
{
public:
void doOrGetSomething() override;
};
现在您的processEvent
函数可能会接受引用,就像fsm
的变体一样:
void processEvent(MyStateMachineEvent& event)
{
fsm.processEvent(event);
}
void FSM::processEvent(MyStateMachineEvent& event)
{
// ...
event.doOrGetSomething();
// ...
}
用法可能如下:
std::queue<std::unique_ptr<MyStateMachineEvent>> events;
events.emplace(new EventChild());
processEvent(**events.front());
events.pop();