【问题标题】:Function-wide exception handling in c++ - is it a bad style?c++ 中的函数范围异常处理 - 这是一种不好的风格吗?
【发布时间】:2010-10-11 20:54:22
【问题描述】:

关于函数有一个try-catch的东西,我认为有时它可能非常有用:

bool function() 
try
{
    //do something
}
catch(exception_type & t)
{
   //do something
}

所以问题的第一部分:这种风格在一般情况下被认为是不好的吗?

我使用这种方法的具体例子是:

我们的项目包含大量 c 和 c++ 代码。我们有自定义异常类型(不是 std::exception 派生的)。我需要集成 XML 库并将所有异常转换为我们的类型。因此,基本上,最后一步是从 XML 库中捕获所有异常并进行转换。

之前的功能:

bool readEntity(...)
{
   while(...)
   { 
      if(...)
      {
         //lot's of code...
      }
   }
}

之后:

bool readEntity(...)
try
{
   while(...)
   { 
      if(...)
      {
         //lot's of code...
      }
   }
}
catch(XMLBaseException & ex)
{
    //create our exception and throw
}

我的想法是这样的:我明确表示我打算将所有从一种类型派生的异常转换为自定义类型,并且我们保持屏幕没有水平滚动条(因为水平滚动条不好)。

好吧,我实际上因为这种方法而受到批评,因为我在代码审查期间因为不清晰的方法而受到批评。

所以我想听听你的想法。

更新:明确一点:重构函数不是一种选择。实际上写得很好。

【问题讨论】:

标签: c++ exception coding-style


【解决方案1】:

实际上,函数级 try 块的唯一原因是构造函数,否则它是一个有点晦涩难懂的特性,不会给你带来太多好处。这样做也很容易:

bool readEntity(...)
{
   try
   {
      while(...)
      { 
         if(...)
         {
            //lot's of code...
         }
      }
   }
   catch(XMLBaseException & ex)
   {
       //create our exception and throw
   }
}

如果您在水平滚动时遇到问题,那么要做的就是拆分您的代码。 try/catch 很复杂,应该在嵌套级别表示,而不是隐藏。

在构造函数中,这是一个不同的问题:没有其他方法可以在初始化列表中捕获异常:

SomeClass::SomeClass(parameter p1, parameter p2) : Member1(p1), Member2(p2)
try
{ 
}
catch(Exception &ex)
{
    // handle and rethrow
}

当然,如果您在构造过程中遇到异常,除了 log 和 rethrow(在构造函数的情况下无论如何都会被重新抛出)之外,您可能无法恢复。您的对象尚未完全构建,您无法真正用它做任何事情。您唯一可以相信有效的是参数(尽管如果初始化失败,那很可能是由于参数错误)。

请参阅GOTW 了解有关此问题的讨论。

【讨论】:

    【解决方案2】:

    要明确一点:重新抛出和重新打包异常并不是不好的做法,这是一件好事,因为它可以最大限度地减少外部依赖项的暴露。

    然而,函数级的 try-catch 是为构造函数初始化而设计的。在代码中保存几个水平空格不值得使用相对晦涩的语言功能。如果你真的缩进那么远,最好重构嵌套代码!

    【讨论】:

      【解决方案3】:

      该函数应该返回一个布尔值,因此您可以返回一个真或假,但是如果该函数失败并且该布尔值用于成功标志以外的其他东西(除非纯c,否则这是不好的做法)它应该抛出向调用者发出信号它不起作用。

      【讨论】:

      • 函数类型只是举例。我认为它返回了刚刚创建的实体。但我明白你的意思。
      【解决方案4】:

      Herb Sutters GotW site 上有关于构造函数/函数 try 块的一般无用性的很好讨论。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多