如何通过许多步骤跟踪状态

时间:2013-12-03 07:24:47

标签: c++ status

我正在处理一些因为状态检查而难以重新考虑的代码。我试图找出更好的解决方法,以便我可以保持我的代码清洁/可读。以下是代码的代码:

int status = FAILED;

status = fn_action_one();

if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_one()\n");
}
else
{
    status = fn_action_two();
}

if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_two()\n");
}
else
{
    status = fn_action_three();
}

对我来说问题是我现在想要重构这段代码并循环遍历它的一部分:

int status = FAILED;

status = fn_action_one();

if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_one()\n");
}
else
{
    // This task is now required to be done multiple times...
    for (int i = 0; i < numLoop; i++)
    {
        status = fn_action_two(i); // Keeping track of the status here is now an issue
    }
}

// If any of the looped action_two's had a fail this check should fail
if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_two()\n");
}
else
{
    status = fn_action_three();
}

这现在变得很困难,因为在循环时我想要在所有numLoop次循环(无论是什么),但如果一个失败,状态应该保持失败。

有干净的方法吗?或者可能有这种模式?

编辑:枚举状态值

enum status_vals
{
    SUCCESS = 0,
    FAILED = -1,
    FAILED_TIMEOUT = -2,
    FAILED_FATAL = -3,
        etc...
}

3 个答案:

答案 0 :(得分:3)

'模式'是使用异常处理。如果你不能修改fn_action_xxx()然后写包装器

void my_action_one()
{
    int status = fn_action_one();
    if (status != SUCCESS)
         throw std::runtime_error("ERROR: returned from fn_action_one()");
}

...

try
{
    my_action_one();
    for (int i = 0; i < numLoop; i++)
    {
        my_action_two(i);
    }
    my_action_three();
}
catch (const std::exception& e)
{
    printf("%s\n", e.what());
}

状态检查的脆弱性是异常的动机之一。通过将错误处理与程序的主流分离,您可以获得更清晰的代码。

答案 1 :(得分:1)

作为有点“C”方法,我会使用宏和goto的组合。

#define CHECK(expr) \
  { \
    if( SUCCESS != (status = expr) ){ \
    printf("ERROR: returned from " #EXPR "\n"); \ 
    goto End
  } \
}


int status = FAILED;

CHECK(fn_action_one());

End:
return status;

在循环内我会做

  if (status != SUCCESS)
  {
     status = fn_action_two(i);
  }

答案 2 :(得分:1)

如果你想尽可能地保持当前的代码结构,并尽量减少实现所需功能所需的更改,你可以通过添加一个布尔值来跟踪循环中的任何调用是否失败,然后根据以下内容设置status

int status = FAILED;

status = fn_action_one();

if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_one()\n");
}
else
{
    bool failed = false;
    // This task is now required to be done multiple times...
    for (int i = 0; i < numLoop; i++)
       failed |= (fn_action_two(i) == FAILED);
}
if (failed)
    status = FAILED;

// If any of the looped action_two's had a fail this check should fail
if (status != SUCCESS)
{
    printf("ERROR: returned from fn_action_two()\n");
}
else
{
    status = fn_action_three();
}