C++ C++;错误处理模式

C++ C++;错误处理模式,c++,error-handling,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")

我们有一个庞大的代码库,其中包含大量的代码,可以完成这类工作:

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;
}
我们考虑了各种备选方案:

  • 例外情况-基本上,我们销售的是如下所述的cons:
  • 传递一个额外的字符串ref parm,该字符串填充了错误文本,但它需要在调用之前预先实例化错误字符串,并将bulk添加到parm列表中
  • 填充“last_error”成员变量-这似乎存在(imo)此处表示的缺点:
  • 传回一个枚举(或类似的),该枚举可以映射到某个其他函数的错误描述,但这对于小函数和对象来说感觉“沉重”,并且在错误发生的位置和消息维护的位置之间创建了空间(虽然我认为在多语言环境中,他们会欣赏文本的集中)
所以我想知道我们是否可以创建一组类,如下所示:

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();
}
我喜欢的是:

  • 代码仍然可读,并且错误消息保持在错误条件附近
  • 程序员将被迫在错误条件下实际提供错误字符串(是的,他们可以提供空格,但这似乎是一个更严重的错误,依我看)
  • 调用方不必在函数调用之前创建任何专用变量,并且仍然可以将函数结果视为bool,或者在不忽略错误的情况下,可以轻松检索解释
  • 下一个程序员只需查看函数定义就可以知道正在使用什么错误模型
我看到的主要缺点是,成功的开销更大,一个对象、一个字符串和一个bool都将被实例化——但在我们的应用程序中,很多时候所讨论的代码对性能不敏感,比如验证用户输入等


我是否遗漏了其他一些大缺点?是否有更好的解决方案?

将“错误”分为两类是很有用的:

致命错误

这些都是恢复毫无意义的错误

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

是否有更好的解决方案?是的,使用异常。至于那些缺点,不做某事,因为它可能更困难,但更好的是没有理由和资源?任何自重的C++程序都会使用智能指针,使他们的声明无效,导致资源泄漏。lly checked return values+MANUAL MANAGLE MANAGLE MANAGLE raw pointers=更慢、更麻烦。@Rafaelbatista鉴于异常只应在异常情况下发生,您的注释毫无意义。代码很少在异常路径上进行速度优化,因为这些异常不会定期发生。如果您的代码抛出大量异常,请按专业说明bably有问题。如果你对控制流使用异常,那你就错了。@RafaelBaptista:No.异常+boost::shared_ptr=所有内存在正确的时间释放。
void check_ex(bool cond, const string& msg)
{
  if (!cond)
  {
    // eventually log it somewhere
    throw std::runtime_error(msg);
  }
}