我在状态机中调用了很多外部函数 - 明确地像sendMessage(...)
或隐含地像a!=b
。到目前为止,我已经尝试跟踪可以抛出的东西,但随着数量的增长,需要更好的方法。缺少异常并允许它传播到状态机框架的代码中显然会引起很多混乱。
我看到三个选项,但我希望有人能指出我更好的选择:
在try catch
,onEntry
和onExit
添加action
。由于它们很多并且它们非常好,所以这几乎会使代码长度增加一倍并降低可读性。
制作大量函数noexcept
。如果在其他地方使用该函数,或者它可以合法地抛出,并且异常是唯一的好解决方案,这似乎是不可能的。
修改我调用的大多数函数,使用alexandrescu的Expected<T>
作为返回类型。请参阅:http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C
哪个选项最好?是否有更好的策略?
答案 0 :(得分:0)
不是将每个onEntry, onExit
和action
包装在try catch块中,更好的方法是实现onEntry,onExit和仅调用onEntry, onExit
的动作的noexcept包装器版本。在try catch块中action
并处理抛出的任何异常。
在代码中,您只需调用包装器而不是实际函数,使用异常处理有利于您,但避免重复尝试/捕获逻辑。
void onExitWrapper(int arg1, int arg2) noexcept
{
try
{
onExit(arg1,arg2);
}
catch(/*whatever*/)
{
//handle exception
}
}
如果异常处理对于不同的函数是相似的,你也可以创建接收函数指针/ lambda和输入参数的特殊函数,并调用函数指针引用的函数和try catch中的输入参数:
template <class Arg1,class Arg2,class Ret> Ret exceptionHandler(Ret (funcPtr *)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)
{
Ret output;
try
{
output = funcPtr(arg1,arg2);
}
catch(/*whatever*/)
{
//handle exceptions
}
return output;
}