C ++错误处理模式

时间:2012-07-06 16:19:59

标签: c++ error-handling

我们有一个很大的代码库,有很多代码可以做这种事情:

bool DoSomething(CString Value)
{
   if(Value == "bad")
   {
       AfxMessageBox("description of error");
       return false;
   }
   return true;
}

甚至只是这个:

bool DoSomething(CString Value)
{
   if(Value == "bad")
   {
      return false;
   }
   return true;
}

我们考虑了各种替代方案:

  • 例外情况 - 基本上我们按照此处所述的利弊出售:http://www.codeproject.com/Articles/38449/C-Exceptions-Pros-and-Cons
  • 传递一个附加的字符串ref parm,其中填充了错误文本 - 但它需要在调用之前预先实例化错误字符串,并将批量添加到parm列表
  • 填充'last_error'成员变量 - 这似乎遭受(imo)此处表达的缺点:Is GetLastError() kind of design pattern? Is it good mechanism?
  • 将可以映射到错误描述的枚举(或类似物)与其他函数一起传回 - 但这对于小函数和对象来说感觉“很重”,并且还会在错误发生的位置之间创建空间。消息保存的地方(虽然我认为在多语言环境中他们会欣赏文本的集中化。)

所以我想知道我们是否可以创建一组类,如下所示:

class CResult
{
protected:
   CResult()
   {
      // Don't have to initialize because the derived class will do it
   }
public:
   operator bool() { return m_Result; };

   bool m_Result;
   CString m_Message;
};

class CSuccess : public CResult
{
public:
   CSuccess()
   {
       m_Result = true;
   }
};

class CFailure : public CResult
{
public:
   CFailure(const CString & Message)
   {
      m_Result = false;
      m_Message = Message;
   }
};

然后上面的代码看起来像这样:

CResult DoSomething(CString Value)
{
   if(Value == "bad")
   {
      return CFailure("description of error");
   }
   return CSuccess();
}

我喜欢它:

  • 代码仍然可读,并且错误消息保持在错误条件
  • 附近
  • 程序员将更加强迫在错误条件下实际提供错误字符串(是的,他们可以提供空白,但这似乎是一个更加严重的错误,imo)
  • 调用者不必在函数调用之前创建任何专用变量,并且仍然可以将函数结果视为bool - 或者在不忽略错误的情况下,轻松检索解释
  • 下一个程序员可以通过查看函数定义
  • 来使用什么错误模型

我看到的主要缺点是成功的开销更高,因为对象和字符串以及bool都将被实例化 - 但在我们的应用程序中,很多时候所讨论的代码对性能不敏感,例如验证用户输入等

我错过了一些其他的大缺点吗?还有更好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

将“错误”分为两类非常有用:

致命错误

这些是一种错误,恢复是没有意义的。

void check(bool cond, const string& msg)
{
  if (!cond)
  {
    // eventually log it somewhere
    std::cerr << "Fatal: " << msg << std::endl;
    exit(1);
  }
}

例外错误

这些是您可以从中恢复并使程序保持运行状态的错误。

void check_ex(bool cond, const string& msg)
{
  if (!cond)
  {
    // eventually log it somewhere
    throw std::runtime_error(msg);
  }
}
相关问题