了解C++编程中指定的异常和未经处理的异常
noexcept
C++11:指定函数是否可能会引发异常。
语法
ReturnTypeFunctionName(params)noexcept; ReturnTypeFunctionName(params)noexcept(noexcept(expression);
参数
表达式
计算结果是True或False的常量表达式。无条件版本相当于noexcept(true)。
备注
noexcept(及其同义词noecept(true))指定函数绝不会引发异常,或允许从异常直接或间接调用的任何其他函数传播异常。更具体地说,noexcept意味着,仅当调用的所有函数也为noexcept或const并且没有要求运行时检查、应用于类型为多态类类型的glvalue表达式的typeid表达式或throw表达式的潜在已评估转换时,该函数才是noexcept。但是,编译器不一定会检查可能归因于noexcept函数的异常的每个代码路径。如果异常确实到达标记为noexcept的函数,则会立即调用std::terminate,并且不会保证将调用任何范围内对象的析构函数。
使用条件noexcept声明的且计算结果为noexcept(false)的函数指定它确实允许传播异常。例如,当要复制的对象是普通的旧数据类型(POD)时,可将复制其参数的函数声明为noexcept。此类函数可以如下声明:
#include<type_traits> template<typenameT> Tcopy_object(T&obj)noexcept(std::is_pod<T>) { //... }
使用noexcept代替异常说明符throw,后者在C++11和更高版本中已弃用。当你确信函数绝不允许异常传播到调用堆栈时,我们建议你将noexcept应用到函数。使用noexcept声明的函数使编译器可以在多种不同的上下文中生成更高效的代码。
未经处理的C++异常
如果无法找到当前异常的匹配处理程序(或省略号catch处理程序),则调用预定义的terminate运行时函数。(您也可以在任意处理程序中显式调用terminate。)terminate的默认操作是调用abort。如果您希望terminate在退出应用程序之前调用程序中的某些其他函数,则用被调用函数的名称作为其单个参数调用set_terminate函数。您可以在程序的任何点调用set_terminate。terminate例程总是调用指定为set_terminate的参数的最后一个函数。
以下示例引发char*异常,但不包含用于捕获类型char*的异常的指定处理程序。对set_terminate的调用指示terminate调用term_func。
//exceptions_Unhandled_Exceptions.cpp //compilewith:/EHsc #include<iostream> usingnamespacestd; voidterm_func(){ cout<<"term_funcwascalledbyterminate."<<endl; exit(-1); } intmain(){ try { set_terminate(term_func); throw"Outofmemory!";//Nocatchhandlerforthisexception } catch(int) { cout<<"Integerexceptionraised."<<endl; } return0; }
输出:
term_funcwascalledbyterminate.
term_func函数最好是通过调用exit来终止程序或当前线程。如果它没有这样做,而是返回到其调用方,则调用abort。