这三者之间的区别是什么,我应该如何结束程序的情况下,我不能正确处理异常?
我的建议是不要使用其中任何一个。相反,在 main()中无法处理的异常是 catch,而在 return中只能处理这些异常。这意味着可以保证正确地进行堆栈展开并调用所有析构函数。换句话说:
main()
catch
return
int main() { try { // your stuff } catch( ... ) { return 1; // or whatever } }
Abort 表示程序的“异常”结束,并引发 POSIX 信号 SIGABRT,这意味着您为该信号注册的任何处理程序都将被调用,尽管在这两种情况下程序仍将在后面终止。通常,在 C 程序中使用 abort可以避免出现意外的错误情况,这种情况下错误很可能是程序中的 bug,而不是像错误输入或网络故障这样的情况。例如,如果发现一个数据结构中有一个 NULL 指针,而在逻辑上不应该发生这种情况,那么可以使用 abort。
abort
Exit 表示程序的“正常”结束,尽管这可能仍然表示失败(但不是 bug)。换句话说,如果用户提供的输入无法解析,或者文件无法读取,那么您可能会使用错误代码 exit。退出代码为0表示成功。exit还可以在结束程序之前调用处理程序。这些函数用 atexit和 on_exit函数注册。
exit
atexit
on_exit
在 C + + 程序中,当出现未处理的异常时,会自动调用 std: : finally 。这实际上是与 abort等价的 C + + ,假设您通过抛出异常来报告所有异常错误。这将调用由 std::set_terminate函数设置的处理程序,该函数在默认情况下仅调用 abort。
std::set_terminate
在 C + + 中,您通常希望避免在出现错误时调用 abort或 exit,因为最好抛出一个异常,并让调用堆栈上的代码决定是否应该结束程序。是否使用 exit获得成功是一个环境问题——在 main中的 return 语句之外的其他地方结束程序是否有意义。
main
即使在 C + + 中,std::terminate也应该被认为是最后的错误报告工具。std::terminate的问题在于终止处理程序确实能够访问未处理的异常,所以没有办法知道它是什么。通常最好将整个 main 包装在一个 try { } catch (std::exception& ex) { }块中。至少您可以报告关于从 std::exception派生的异常的更多信息(当然,不是从 std::exception派生的异常最终仍然是未处理的)。
std::terminate
try { } catch (std::exception& ex) { }
std::exception
在 try { } catch(...) { }中包装 main的主体并不比设置终止处理程序好多少,因为您同样无法访问所讨论的异常。但是,至少有一个好处: 当异常完全未捕获时,堆栈解除是否已完成,这是实现定义的,因此如果需要确保堆栈解除,这将是一种实现方法。
try { } catch(...) { }
会自动调用 finally () 当发生不能 默认情况下,终止() 调用 abort () 函数的句柄。
Abort ()发送 SIGABRT 信号。
Exit ()不一定是坏的 事件。它成功退出 应用程序和 exit ()调用 按照后进先出顺序运作,我没有 通常在 C + + 中看到这个 然而,我确实看到了它的应用 许多基于 Unix 的应用程序 最后发送一个退出代码。 通常出口(0)表示 应用程序运行成功
Abort 和 std: : Exit (以及更多: std: : _ Exit,std: : fast _ Exit)只是较低级别的函数。你用它们来告诉程序你想要它做什么: 调用什么析构函数(如果) ,调用什么其他的清理函数,返回什么值,等等。
Finally 是一个更高层次的抽象: 它被调用(由运行时或您)来指示程序中发生了错误,并且由于某种原因不可能通过抛出异常来处理。这样做的必要性通常发生在异常机制本身发生错误时,但是当您不希望程序在给定的错误之后继续运行时,可以随时使用它。当 std: : finally 被称为 在我的岗位上时,我编译了完整的情况列表。它没有指定 std: : finally 的作用,因为您可以控制它。您可以通过注册任何函数来配置行为。您所受到的限制是,函数不能返回到错误站点,也不能通过异常退出,但是从技术上讲,您甚至可以在内部启动消息泵。有关您可以在里面做的有用事情的列表,请参见 我的另一个职位。
特别要注意的是,在 std: : finally 由于无法处理抛出的异常而被调用的上下文中,std: : finally 被认为是一个异常处理程序,您可以检查异常是什么,并使用 C + + 11使用 std: : rethrow _ Exception 和 std: : current _ Exception 检查异常。都在 我的岗位里。
Quick _ exit () !
如果您的程序是多线程的,那么调用 exit()很可能会导致崩溃,因为全局/静态 std::thread对象将尝试在不退出其线程的情况下进行销毁。
exit()
std::thread
如果希望返回错误代码并正常退出程序(或多或少) ,请在多线程程序中调用 quick_exit()。 对于异常终止(无法指定错误代码) ,可以调用 abort()或 std::terminate()。
quick_exit()
abort()
std::terminate()
注: MSVC + + 不支持 fast _ exit ()直到2015年版本。