如何从C ++ catch(...)块获取错误消息?

时间:2016-10-31 13:30:01

标签: c++ try-catch

所以,我正在查看try / catch块的C++ reference

我看到有几种方法可以像这样捕获异常:

try {
    f();
} catch (const std::overflow_error& e) {
    // this executes if f() throws std::overflow_error (same type rule)
} catch (const std::runtime_error& e) {
    // this executes if f() throws std::underflow_error (base class rule)
} catch (const std::exception& e) {
    // this executes if f() throws std::logic_error (base class rule)
} catch (...) {
    // this executes if f() throws std::string or int or any other unrelated type
}

我在以下示例中看到您可以捕获“e”数据,如下所示:

std::cout << e.what();

所以我的问题归结为:

如何在catch(...)上获取异常数据?

(附带问题:使用catch(...)是否明智?)

2 个答案:

答案 0 :(得分:7)

一般情况下,你不能。 C ++几乎可以抛出任何东西。例如,throw 42;是完全定义良好的C ++代码,异常的类型是int

至于使用它是明智的 - 有效用途:

  • 如果抛出异常并且没有任何catch块,则调用std::terminate并且无法保证堆栈展开。 catch(...)保证(因为它捕获了任何异常)。

int main()
{
    super_important_resource r;
    may_throw();
    // r's destructor is *not* guaranteed to execute if an exception is thrown
}

int main()
try {
    super_important_resource r;
    may_throw();
    // r's destructor is guaranteed to execute during stack unwinding
} catch(...) {
}
  • 在重新抛出异常之前,记录异常被抛出是一个有效的用例。

try {
//...
} catch(...) {
    log() << "Unknown exception!";
    throw;
}

答案 1 :(得分:1)

  

如何在catch(...)上获取异常数据?

一般情况下,您无法获得任意异常。但是,如果异常类型是已知类型之一,则可以重新抛出当前异常并捕获它。

  

附带问题:使用catch(...)是否明智?)

使用at作为后备选项来处理意外异常是有意义的。人们可以考虑采用重新捕获技术来避免在几个地方对捕获系列进行复制粘贴。

void Catcher()
{
    try
    {
        throw;
    }
    catch (const std::overflow_error& e) {
        // this executes if f() throws std::overflow_error (same type rule)
    }
    catch (const std::runtime_error& e) {
        // this executes if f() throws std::underflow_error (base class rule)
    }
    catch (const std::exception& e) {
        // this executes if f() throws std::logic_error (base class rule)
    }
    catch (...) {
        // oops!
    }
}

int main()
{
    try {
        f();
    }
    catch (...) {
        Catcher();
    }
}
相关问题