我已经习惯于按如下方式构建我的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;产生错误?
答案 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中,它将被忽略。