将参数传递给函数,获取父类参数,而不将参数强制转换为父类



我正在构建一个 Boost 状态机。我的状态有一个指向它自己的后端(fsm)的指针来处理事件。我的状态机的所有事件都是MySatetMachineEvent类的子级(带有像EventChild这样的示例子级)。状态转换仅针对像MySTateMachineEventEventChild这样的孩子定义。
为了清理我的代码,我想创建一个函数processEvent(MySatetMachineEvent event)获取所有可能的事件。然后,此类应使用传递的事件调用process_event()函数。 例如:

processEvent(MyStateMachineEvent event)
{
fsm.process_event(event);
}
processEvent(EventCild());

应该调用

fsm.process_event(EventChild());

创建这样的函数会导致错误,即使用MyStateMachineEvent的实例调用fsm.process_event()。如上所述,没有为这种情况定义状态转换。

显然,这阻碍了我的状态机以正确的方式工作。


所以我的问题是是否有办法将MyStateMachineEvent的任何EventChild或其他子项传递给我的processEvent(MySTateMachineEvent event)函数,而无需将传递的对象转换为MyStateMachineEvent


我知道覆盖我的函数的解决方案,例如

processEvent(EventChild event) {
fsm.process_event(event);
}

在我的情况下,这将导致可能函数(内部具有完全相同的代码行),因此我正在寻找更干净,更花哨的解决方案。

您可以使用函数模板:

template <typename Event>
void processEvent(Event event)
{
fsm.process_event(event);
}

每个实例化都将保留传入的event参数的确切类型。

尽管我喜欢 Vittorio Romeo 的模板方法,但如果您例如有某种事件队列保存任意事件,它可能不合适。多态方法可能更合适:

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();

最新更新