C++ 如何防止boost::statetechart因引发异常而终止
我已经实现了一个继承boost::statechart的状态机。当我调用C++ 如何防止boost::statetechart因引发异常而终止,c++,boost-statechart,C++,Boost Statechart,我已经实现了一个继承boost::statechart的状态机。当我调用fsm.process\u event(some\u event())哪个反应会引发异常时,结果是在我使用try-catch-block处理异常后,我的statemachine实例fsm被终止。也就是说,fsm.terminated()返回true。在某些情况下,我不希望它被终止。例如,当我希望状态机抛出异常以通知调用方非处理事件的fsm.process\u event(unrelated\u event()),并将其当前状
fsm.process\u event(some\u event())
哪个反应会引发异常时,结果是在我使用try-catch-block处理异常后,我的statemachine实例fsm
被终止。也就是说,fsm.terminated()
返回true
。在某些情况下,我不希望它被终止。例如,当我希望状态机抛出异常以通知调用方非处理事件的fsm.process\u event(unrelated\u event())
,并将其当前状态保持在事件状态之前
简而言之-如何防止boost::statechart
在抛出异常后终止,并将其保持在异常之前的状态
示例代码:
namespace sc = boost::statechart;
class State;
struct some_event : public sc::event<some_event> { };
class FSM
: public sc::state_machine< FSM, State, std::allocator<void>, sc::exception_translator<> >
{
public:
FSM()
{
cout<<"FSM::FSM()"<<endl;
}
virtual ~FSM()
{
cout<<"FSM::~FSM()"<<endl;
}
};
class State : public sc::simple_state< State, FSM >
{
public:
State()
{
cout<<"State::State()"<<endl;
}
virtual ~State()
{
cout<<"State::~State()"<<endl;
}
typedef boost::mpl::list<
sc::custom_reaction< some_event >,
sc::custom_reaction< sc::exception_thrown >
> reactions;
sc::result react( const some_event & e)
{
cout<<"State::react( const some_event &)"<<endl;
throw std::exception();
return this->discard_event();
}
sc::result react( const sc::exception_thrown & e)
{
cout<<"State::react( const sc::exception_thrown &)"<<endl;
throw;
return this->discard_event();
}
};
int main()
{
FSM fsm;
fsm.initiate();
try
{
fsm.process_event(some_event());
}
catch(...)
{
cout<<"Exception caught"<<endl;
}
if(fsm.terminated())
{
cout<<"fsm2 is TERMINATED"<<endl;
}
else
{
cout<<"fsm2 is RUNNING"<<endl;
}
return 0;
}
我希望它输出:
FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is RUNNING
您应该为状态机提供一个自定义异常处理程序。请参见此处的boost文档: 当抛出异常时,状态机不可能知道它是否仍处于有效状态,这就是异常句柄的默认操作是终止sm的原因。您的自定义处理程序可以执行清理/检查,以确保sm处于有效状态,并在不同的庄园中向上传播信息 就我个人而言,我从来没有看到过通过异常从SM传播信息的好理由。这很可能是因为我从未在您的特定领域工作过,但这仍然是我的理性: 如果事件不相关,则忽略它或记录它,同一事件可能在其他状态下相关,而不是当前状态。如果事件无效,即永远不会发生或状态不正确,则为:
- 如果代码有问题,您应该立即断言并处理该问题
- 来自包含SM的模块之外的无效输入问题(硬件连续发布了3个断开连接的事件,这永远不会发生等)。在这种情况下,您无法以任何方式在本地模块中正确处理异常,最好的办法是记录问题并切换到灾难性错误状态或只能保留EvReset或其他功能的状态
FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is RUNNING