功能体异常

Rob*_*obᵩ 1 c++ exception

可能重复:
函数的try-catch语法之间的差异

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

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

int f() try {
  ...
} catch (...) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

And*_*ron 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;
}
Run Code Online (Sandbox Code Playgroud)

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`.
}
Run Code Online (Sandbox Code Playgroud)

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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