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

How to get the error message from a C++ catch(...) block?

本文关键字:获取 取错误 消息 c++ catch      更新时间:2023-10-16

所以,我正在查看try/catch块的c++引用。

我看到有几种方法可以捕获异常,如下所示:

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(...)是否明智?)

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

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

  • 如果抛出一个异常,并且一直没有捕获块,则调用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;
}

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

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

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

使用at作为回退选项来处理意外异常是有意义的。可以考虑使用catch-rethrow技术来避免在多个地方复制粘贴catch系列。

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();
    }
}