为什么我的C++异常没有被捕获?

Cra*_*ger 3 c++ exception-handling exception

我的代码抛出std::runtime_error,但是没有在catch块中捕获它.相反,它只是调用,std::terminate或者,如果我在函数上声明了异常说明符,则调用std::unexpected.

代码简化为:

void myfunc()
{
   throw new std::runtime_error("always throw");
}

int main()
{
    try {
        myfunc();
    } catch (std::runtime_error &err) {
        std::cerr << "intentionally ignored exception: " << err.what() << std::endl;
        return 0;
    }
    std::cerr << "unreachable?" << std::endl;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

同样,如果我throw在我的函数上添加一个说明符,我会崩溃std::unknown.

void myfunc() throw (std::runtime_error)
{
   throw new std::runtime_error("always throw");
}
Run Code Online (Sandbox Code Playgroud)

Cra*_*ger 10

你陷入了Java主义:

throw new std::runtime_error("always throw")
      ^^^
Run Code Online (Sandbox Code Playgroud)

这将导致catch子句不匹配,因为它的类型相匹配,你扔std::runtime_error*,即指向一个std::runtime_error.它期待一个简单std::runtime_error 的参考.

您可以(未经测试)捕获您的原始异常

catch (std::runtime_error * exc) /* don't do this */
Run Code Online (Sandbox Code Playgroud)

但你不应该这样做.

而是跳过new; 直接抛出你的异常并写:

void myfunc()
{
   throw std::runtime_error("always throw");
}
Run Code Online (Sandbox Code Playgroud)

C++足够聪明,如果你通过引用捕获异常,它将不会被复制.

另外,正如@KonradRudolph在评论中指出的那样,你应该通过const-reference来捕获:

catch (const std::runtime_error &err)
Run Code Online (Sandbox Code Playgroud)