在try catch块中未捕获的异常

5

我执行了一个简单的 throw "TEST THROW",但它没有被我的 catch (std::exception& e) 捕获。这是因为我捕获的是 std::exception& e 吗?也就是说,只有从 std::exception 继承的异常类才会被捕获吗?如果不是,那么我是做错了什么,还是这是正常现象?顺便说一下,两个 catch 块都没有捕获到抛出的异常。

int main()
{
try
{
    throw "TEST THROW"; // TEST
    Core core;

    core.Init();
    core.Load();

    while (!core.requestCloseWindow)
    {
        core.HandleInput();

        core.Update();
        core.Draw();
    }

    core.Unload();
    core.window->close();
}
catch (std::exception& e)
{
    std::cerr << e.what() << std::endl;
    try
    {
        time_t rawTime;
        struct tm* timeInfo;
        char timeBuffer [80];

        time(&rawTime);
        timeInfo = localtime(&rawTime);

        strftime(timeBuffer, 80, "%F %T", timeInfo);
        puts(timeBuffer);

        std::ofstream ofs; // Pas besoin de close, car le destructeur le fait.
        ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit);
        ofs.open("log.txt", std::ofstream::out | std::ofstream::app);
        ofs << e.what() << std::endl;
    }
    catch (std::exception& e)
    {
        std::cerr << "An error occured while writing to a log file!" << std::endl;
    }
}

return 0;

}


6
您没有抛出一个 std::exception 类型的对象,因此该异常不会被设计用于捕获 std::exception 类型对象的 catch 子句所捕获。 - Igor Tandetnik
我认为你可以使用catch (const char*)或string。 - Tim3880
你希望发生什么?e将是什么? - Raymond Chen
5个回答

14

另一个可能导致这个问题的原因是,特别是那些最近一直在编写Java代码的人,可能会抛出异常指针

/* WARNING WARNING THIS CODE IS WRONG DO NOT COPY */
try {
    throw new std::runtime_error("catch me");
} catch (std::runtime_error &err) {
    std::cerr << "exception caught and ignored: " << err.what() << std::end;
}
/* WARNING WARNING THIS CODE IS WRONG DO NOT COPY */

如果你抛出的是 std::runtime_error*,它将不会被捕获。程序可能会因未捕获异常而调用std::terminate导致崩溃。

不要使用 new 分配异常对象,直接通过值传递构造函数抛出异常,例如:

try {
    /* note: no 'new' here */
    throw std::runtime_error("catch me");
} catch (std::runtime_error &err) {
    std::cerr << "exception caught and ignored: " << err.what() << std::end;
}

傻我!你救了我的一天。 - Doodler
哇,谢谢啊!这正是我需要的,我从Java转到C++还很新手哈哈。 - Vimuth
谢谢这个建议,我最擅长C#,而使用throw new是在这种语言中的处理方式。花了大量时间在各处添加异常处理,但仍然无法捕获异常。这个建议真的帮了我! - Greg Cobb
你根本不知道我在解决这个问题之前花了多少时间咒骂它,直到我自己找到答案。因此,才有了这个回答。 - Craig Ringer

7
你正在抛出一个 const char*。只有捕获 std::exception 及其所有派生类才能处理它。因此,为了捕获你的 throw,你应该抛出 std::runtime_error("TEST THROW") 或者 std::logic_error("TEST THROW");取决于哪个更适合。 std::exception 的派生类在 这里列出

2
你可以添加一个catch (...)块以获取它。

他正在进行catch操作,但却捕获了错误的异常。 - Algo
catch(...) 会捕获他抛出的异常。我不明白为什么要点踩。 - Baum mit Augen
2
这就像是说:“好的,你正在学习木雕艺术,拿着这个链锯开始制作你的第一个雕像”,最好有一种解决方案来引导他们学习纠正问题的正确方式。 - exs
1
如果我们一开始就能把所有东西都写对,那就太好了。在这种情况下,我喜欢先建立起一些能够工作的东西,然后再从中进行改进。 - donjuedo

2
这也可能发生在你抛出一个继承类型的异常,但继承是私有的。

0

由于这不是一个 MCVE(什么是 Core?),我无法明确解决问题,但你肯定错过了

#include <exception>

实际上,即使没有包含文件,GCC也可以编译,但是异常将不会被捕获,你最终会得到以下错误消息:

terminate called after throwing an instance of 'std::exception'

what(): std::exception

./{program}: {PID} Aborted (core dumped)


为什么会发生这种情况? - Hassen Dhia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接