该标准定义了三种结束 C++ 程序执行的方法:
- 从
main
. 具有自动存储(功能本地)的对象已被销毁。具有静态存储(全局、静态类、静态函数)的对象将被销毁。
std::exit
从<cstdlib>
. 具有自动存储功能的对象不会被销毁。具有静态存储的对象将被销毁。
std::abort
从<cstdlib>
. 具有自动和静态存储的对象不会被破坏。
同样相关的是std::terminate
来自<exception>
. 的行为terminate
可以使用 替换std::set_terminate
,但必须始终通过调用或一些类似的特定于实现的替代方法terminate
来“终止程序的执行” 。abort
默认只是{ std::abort(); }
.
std::terminate
每当抛出异常并且 C++ 无法合理地进行堆栈展开时,C++ 都会调用。例如,堆栈展开调用的析构函数的异常或静态存储对象构造函数或析构函数的异常。在这些情况下,没有(更多)堆栈展开。
当找不到std::terminate
匹配的处理程序时, C++ 也会调用。catch
在这种情况下,C++ 可以选择在main
调用terminate
. 因此,您的示例使用不同的编译器可能会产生不同的结果。
因此,如果您正确使用 RAII,“防泄漏”程序的其余步骤是:
- 避免
std::abort
。
- 避免
std::exit
或避免所有具有静态存储持续时间的对象。
- 将
catch (...)
处理程序放入 中main
,并确保在其中或之后没有分配或异常发生。
- 避免其他可能导致的编程错误
std::terminate
。
- (在某些实现中,使用 C 编译器编译的函数就像它们具有 C++ 的空
throw()
规范一样,这意味着即使它们没有要调用的析构函数,也不能“过去”抛出异常。)