异常也有出错的时候

1、不能捕获的异常。函数的异常声明必须与catch匹配才行,否则异常不会被捕获,这时的异常会导致程序终止。这时C++并不是直接调用abort,而是通过调用terminate,再由terminate调用abort来终止程序执行。你可以改变这种默认的行为,方法就是由你自己设置terminate的调用过程。如下图所示:


异常也有出错的时候_第1张图片

下面看到的就是这些函数的用法:



其中myQuit是自定义的函数,这个set_terminate设置terminate调用myQuit函数。上面那个terminate_handler代表一个函数指针,它代表形参列表为空并且返回值为空的函数,这样一个没有任何输入和返回值的函数比较适合做终止函数来使用。
2、未知的异常。很多情况下,你不知道你的程序会抛出啥异常,而函数的异常声明却是明确地给出了可能抛出的异常。众所周知天有不测风云人有旦夕祸福,你哪能对程序的走向把握的面面俱到呢。

如果函数A调用了函数B,B使用了异常声明,你也需要把A写上同样的函数声明。这是一种良好的做法,并不是语法规则,除非你能确保A能完美地处理B抛出的异常,否则你还是把这个异常传递出去的好。
如果真的抛出的未知的异常,C++会自动调用unexpected函数,unexpected再调用terminate,当然这是在默认情况下。



异常也有出错的时候_第2张图片

Normal
0
10 pt
0
2
false

false
false
EN-US
ZH-CN
X-NONE

$([{£¥·‘“〈《「『【〔〖〝﹙﹛﹝$(.[{£¥
!%),.:;>?]}¢¨°·ˇˉ―‖’”…‰′″›℃∶、。〃〉》」』】〕〗〞︶︺︾﹀﹄﹚﹜﹞!"%'),.:;?]`|}~¢

/* Style Definitions */table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:Calibri; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-font-kerning:1.0pt;}

从上图可见,这跟1所述自定义函数过程十分相像,你可以通过调用set_unexpected函数来自定义unexpected函数的行为。不过,unexpected_handler可以调用terminate、abort和exit,另外unexpected_handler还可以抛出异常。

它抛出的异常决定于unexpected_handler所指代的函数以及该函数的异常声明。

它分成下面三种情况:

1、如果抛出的异常与异常声明同类型,该异常会被catch捕获。这基本就是用已知的异常类型去代替未知的异常类型;

2、如果抛出的异常与异常声明不匹配,而且异常声明中不包含有bad_exception类型,程序就会调用terminate来终止运行;

3、如果抛出的异常与异常声明不匹配,而且原异常声明中包含bad_exception异常类型,那么抛出的异常会被定为bad_exception类型。

有一种能捕获任何异常的方法。你设计一个自定义的函数,在这个函数中抛出bad_exception异常,如下图所示:


异常也有出错的时候_第3张图片

在这里要说一点就是,你仅仅使用一个throw,后面没有任何异常的话,会导致原来的异常再次被throw。如果函数的异常声明中含有bad_exception类型,throw出来的将是一个bad_exception对象。
然后,用set_unexcepted去加载这个自定义函数。



最后,你在函数的异常声明中添加bad_exception异常类型,并且在catch中捕获该异常类型。如下图所示:

由上图可知函数的异常声明可以有多个异常类型。

你可能感兴趣的:(异常也有出错的时候)