功能体异常

时间:2011-11-02 15:20:12

标签: c++ exception

  

可能重复:
  Difference between try-catch syntax for function

这些try-catch块的效用和行为有何不同?我什么时候比另一种更喜欢一种形式?

int f() {
  try {
    ...
  } catch(...) {
    ...
  }
}

int f() try {
  ...
} catch (...) {
  ...
}

2 个答案:

答案 0 :(得分:6)

如果整个身体必须进入异常块,我倾向于选择第二种形式,因为它更容易阅读(例如减少一个缩进级别)。

但是,这会产生影响的主要地方是构造函数。考虑:

Foo::Foo ()
try : member_with_throwing_constructor(initial_value)
{
}
catch ( ... )
{
     // will process exceptions thrown by `member_with_throwing_constructor`

     // this will be added by the compiler if you
     // don't finish by a `throw ...` statement.
     throw;
}

Foo::Foo ()
    : member_with_throwing_constructor(initial_value)
{
    try
    {
    }
    catch ( ... )
    {
        // does not catch exceptions thrown in constructor
        // of `member_with_throwing_constructor`.
    }
    // can keep processing if `catch` handler does not `return` or `throw`.
}

这两个代码段的行为完全不同。第一个将捕获数据成员构造函数中引发的异常(通常通过初始化程序列表,但默认构造函数也适用)并将自动重新引发异常,因为无法安全地创建实例。第二种形式不包括数据成员初始化,并允许您选择是否保留对象。

我还想在main()中添加一个全局try-catch来帮助调试未捕获的异常。以下代码段:

int main ( int, char ** )
try
{
    // main program...
}
catch ( const std::exception& error )
{
    std::cerr << "Uncaught exception: '" << error << "'." << std::endl;
    return (EXIT_FAILURE);
}
catch ( ... )
{
    std::cerr << "Uncaught exception of unknown type." << std::endl;
    return (EXIT_FAILURE);
}

有些人会争辩说,不捕获异常会导致程序崩溃,您可以获得核心转储来帮助调试。虽然这在调试模式下可能很有用,因为它可以帮助调试器指向引发异常的确切代码行,但我喜欢发送不会崩溃的程序,并且我可以向用户显示一条消息说错误报告已提交。

答案 1 :(得分:2)

函数try-catch块仅在构造函数中有用,即便如此,根本不是很有用。最好忘记它们的存在。