-
问题一:如何判断一个函数是否会抛出异常,以及抛出那些异常?
-
C++提供语法用于声明函数所抛出的异常
-
异常声明作为函数声明的修饰符,写在参数列表后面。
//可能抛出异常 void func1(); //只能抛出的异常类型:char和int void func2() throw(char,int); //不能抛出任何异常 void func3() throw();
-
异常规格说明的意义
-
提示函数调用者必须做好异常处理的准备
-
提示函数的维护者不要抛出其它异常
-
异常规格说明是函数接口的一部分
-
问题二:如果抛出的异常不在声明列表中,会发生什么?
-
函数抛出的异常不在规格说明中,全局unexpected()被调用
-
默认的unexpected()函数会调用全局的terminate()函数
-
可以自定义函数替换默认的unexpected()函数实现
-
注意: 不是所有的C++编译器都支持这个标准行为
-
unexpected()函数的替换
-
自定义一个无返回值无参数的函数,能够再次抛出异常,当异常符合触发函数的异常规格说明时,恢复程序执行,否则,调用全局函数terminate() 函数结束程序
-
调用set_unexpected()设置自定义的异常函数,参数类型为void(*)(),返回值为默认的unexpected()函数入口地址。
// 如果抛出的异常不在声明列表中,会发生什么?.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; void func() throw(int) { cout << "void func() throw(int)" << endl; throw 'c'; } int main() { try { func(); } catch (int) { cout << " catch (int)" << endl; } catch (char) { cout << "catch(char)" << endl; } }
-
VS2019运行结果
void func() throw(int) catch(char)
-
MINGW运行结果
void func() throw(int) terminate called after throwing an instance of 'char'
-
将unexpected()函数替换掉
#include <iostream> #include <string> #include <cstdlib> using namespace std; void func() throw(int) { cout << "void func() throw(int)" << endl; throw 'c'; } void my_unexpected() { cout << "void my_unexpected()" << endl; exit(1); } int main() { set_unexpected(my_unexpected); try { func(); } catch (int) { cout << " catch (int)" << endl; } catch (char) { cout << "catch(char)" << endl; } return 0; }
-
VS2019运行结果(微软的编译器我行我素,没有按照上面说的标准C++规范来)
void func() throw(int) catch(char)
-
MINGW运行结果
void func() throw(int) void my_unexpected()
-
my_unexpected()函数中扔出异常
#include <iostream> #include <string> #include <cstdlib> using namespace std; void func() throw(int) { cout << "void func() throw(int)" << endl; throw 'c'; } void my_unexpected() { cout << "void my_unexpected()" << endl; //exit(1); throw 1; } int main() { set_unexpected(my_unexpected); try { func(); } catch (int) { cout << "catch (int)" << endl; } catch (char) { cout << "catch(char)" << endl; } return 0; }
-
MINGW运行结果
void func() throw(int) void my_unexpected() catch (int)
-
VS2019运行结果
void func() throw(int) catch(char)
-
小结
-
C++中的函数可以声明异常规格说明
-
异常规格说明可以看作接口的一部分
-
函数抛出的异常不在规格说明中,unexpected()被调用
-
unexpected()中能够再次抛出异常,异常能够匹配,恢复程序的执行,否则,调用terminate()结束程序。