【问题标题】:How should I handle exceptions in a state machine?我应该如何处理状态机中的异常?
【发布时间】:2014-02-21 20:26:15
【问题描述】:

我从我的状态机中调用了很多外部函数——要么明确地像sendMessage(...),要么隐含地像a!=b。到目前为止,我一直试图跟踪可以抛出的内容,但随着数量的增长,对更好方法的需求也在增加。错过一个异常并让它传播到状态机框架的代码中显然会造成很多混乱。

我看到了三个选项,但我希望有人能指出一个更好的选项:

  1. 在每个 onEntryonExitaction 处放置一个 try catch。由于它们的数量很多而且它们都很漂亮,这几乎会使代码长度增加一倍并降低可读性。

  2. 制作一大堆函数noexcept。如果函数在其他地方使用,或者它可以合法抛出并且异常是唯一好的解决方案,这似乎是不可能的。

  3. 修改我调用的大部分函数以使用 alexandrescu 的 Expected<T> 作为返回类型。见:http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C

哪个选项最好?还有更好的策略吗?

【问题讨论】:

  • 异常处理程序应该如何处理捕获的异常?我想它只是改变了统计数据。
  • 将异常视为您无法处理的异常。并且总是添加一个错误状态,这样你就不必抛出了。

标签: c++ exception-handling try-catch noexcept


【解决方案1】:

与其将每个onEntry, onExitaction 包装在try catch 块中,更好的方法是实现onEntry、onExit 和操作的noexcept 包装器版本,在try catch 中简单地调用onEntry, onExitaction阻止并处理任何抛出的异常。

在代码中,您只需调用包装器而不是实际函数,使用异常处理对您有利,但避免重复 try/catch 逻辑。

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2020-02-10
    相关资源
    最近更新 更多