尝试/捕捉整个程序

时间:2014-11-02 21:08:04

标签: c++ exception try-catch

我已经习惯于按如下方式构建我的C ++项目:

int main(int ac, char* av[])
{
    try
    {
       Object    foo;

       foo.run()
       /* ... */
    }
    catch (const std::exception& e)
    {
       std::cerr << e.what() << std::endl;
       return 1;
    }
    catch (...)
    {
       std::cerr << "Unknown error." << std::endl;
       return 1;
    }

    return 0;
}

我想知道这是一个好习惯,还是在小块代码上使用try / catch块更好?#34;预期&#34;产生错误?

5 个答案:

答案 0 :(得分:5)

通常,捕获所有异常并不是一个好主意:您只想捕获特定代码片段已准备好以有意义的方式处理的这些异常。

但是,顶级入口点是此规则的一个例外:如果您希望控制在顶层处理异常的方式,则通常会自行捕获所有异常。

然而,实现它的一种常用方法是编写一个看起来像main但具有不同名称的函数:

int entryPoint(int argc, char *argv[]) {
    ... // The real logic goes here
    Object    foo;

    foo.run()
    /* ... */
}

您的代码看起来像这样,永远不会改变:

int main(int ac, char* av[])
{
    try
    {
        return entryPoint(ac, av);
    }
    catch (const std::exception& e)
    {
       std::cout << e.what() << std::cerr;
    }
    catch (...)
    {
       std::cout << "Unknown error." << std::endl;
    }
}

答案 1 :(得分:3)

如果要控制未处理的异常处理方式(如果它们达到顶级级别),您可以将整个程序放入这样的顶级异常处理程序中。

虽然有一个不利之处:标准的崩溃行为是抢先的,这可能意味着你没有得到崩溃转储,因此缺少关于事后调试的重要信息。

此外,它们可能无法达到顶级,但会导致std::unexpected()std::terminate()被调用。

因此,即使您想做自己的事情,std::set_terminate也可能更好。{/ p>

考虑做自己的事情,然后像普通的一样崩溃(你不能用你的全局异常处理程序)。

答案 2 :(得分:2)

优点是你的程序永远不会崩溃(在Linux上它可能会崩溃,因为信号不会被捕获为异常)

但是我可以想到一个缺点:当您调试代码并出现运行时错误时,您不知道它在哪里或看到堆栈。因为你的程序继续从catch中运行。所以不要立即检查发生了什么,你需要再次运行,并希望你会有相同的行为。

另一件事:如果你的程序是多线程的,它将无助于捕获所有异常,因为每个线程都需要捕获自己的异常。

答案 3 :(得分:1)

如果你可以做一些事情从错误中恢复,那么尽可能在接近投掷时尝试/捕获更好。另一方面,捕获每个致命错误可能会使代码混乱不堪。

如果未捕获投掷,则会调用std::terminate,您可以将该函数设置为std::set_terminate的自定义函数。在terminate函数内部,您可以执行throw;重新抛出未捕获的对象然后捕获它。在这种情况下,你最后必须使用catch(...),因为从终止函数抛出并不是一件好事。

答案 4 :(得分:0)

肯定会有所作为......让我们看看如何。

try
{
// code which could throw an exception
}
catch(Myexception& e)    //derived from std::exception
{
//do something.
}
//..some more code.                  //Point_1

让我们说我只想在捕获Myexception之后进行一些操作,然后恢复此功能。捕获异常代码后会到达POINT_1。如果我将它封装在try / catch中,它将被忽略。