3 try-catch语法分析
通过前面的学习,我们了解了try-catch语法的基本使用。但是,C++提供的异常处理机制很全面,下面再具体分析。
发生异常的时候,我们可以主动抛出一个异常,所以,使用throw抛出一个异常。异常可以是一个数值,字符,或者表达式。
抛出的异常可以有try-catch语句捕获。try-catch的语法结构如下:
try-catch的结构为
try
{
被检查的语句
}
catch(异常信息类型[变量名])
{
进行异常处理的语句
}
归纳总结如下:
(1) 被检测的异常代码必须放在try块中,捕获不到异常。
(2) try块和catch块作为一个整体出现,catch块数try-catch结构中的一部分,必须紧跟在try块之后,不能单独使用,在二者之间也不能插入其他语句,例如下面的用法不对:
try
{
....
}
cout << "www.mylinux.vip" << endl; //不能插入其他语句
catch(double)
{
....
}
在一个try-catch结构中,可以只有try块而无catch块。那么,就捕获捕获到抛出的异常信息。
(3) try和catch块中必须有用花括号括起来的复合语句,即使花括号内只有一个语句,也不能省略花括号。
(4) 一个try-catch结构中只能有一个try块,但却可以有多个catch块,以便与不同的异常信息匹配,如:
try
{ ... }
catch(double)
{ ... }
catch(int)
{ ... }
catch(char)
{ ... }
(5) catch后面的圆括号中,一般只写异常信息的类型名,如:
catch(double)
catch只检查所捕获异常信息的类型,而不检查它们的值,例如,a, b, c都是 double 类型,虽然它们的值不同,但在throw语句中写throw a, throw b 或 throw c,作用均相同。因此,如果需要检测多个不同的异常信息,应当由throw抛出不同类型的异常信息。
异常信息可以是C++系统预定义的标准类型,也可以说用户自定义的类型(如结构体或类)。如果由throw抛出的信息属于该类型或其子类型,则catch与throw二者匹配,catch捕获该异常信息。
catch还可以有另外一种写法,即除了指定类型名之外,还指定变量名,如:
catch (double e)
此时,如果throw抛出的异常信息是double类型的变量a,则catch在捕获异常信息a的同时,还使得d获得a的值,或者说d得到a的一个拷贝。什么时候需要这样做呢?有时候希望在捕获异常信息的时候,还能利用throw抛出的值,如:
catch (double e)
{
cout << "throw err = " << e << endl;
}
这时会输出e的值就是抛出的异常信息,有时希望在catch块中显示该对象中的某些信息。这时就需要在catch的参数中写出变量名(类对象名)。
(6) 如果在catch子句中没有指定异常信息的类型,而用了删节号“…”,则表示它可以捕捉任何类型的异常信息,如:
catch (...)
{
cout << "catch all err" << endl;
}
它能捕获所有类型的异常信息。
这种catch子句应放在try-catch结构中的最后,相当于“其他”。如果把它作为第一个catch子句,则后面的catch子句都不起作用。
(7) try-catch结构可以与throw出现在同一个函数中,也可以不在同一函数中。当throw抛出异常信息之后,首先中本函数中选择与之匹配的catch,如果在本函数中无try-catch结构或找不到与之匹配的catch,就转到其上一层去处理,如果其上一层也无try-catch结构,或找不到与之匹配的catch,则再转到更上一层的try-catch结构去处理,也就是说,总是转到离开出现异常最近的try-catch结构去处理。当最近的处理不了,再往上传递异常。
(8) 在某些情况下,在throw语句中可以不包括表达式,如:
throw;
表示“我不处理这个异常,请上级处理”。此时,它将把当前在处理的异常信息再次抛出,给其上一层的catch块处理。如:
catch(...)
{
.....
throw; //将已捕获的异常信息再次原样抛出,由上一层的catch处理器处理
}
(9) 如果throw抛出的异常信息找不到与之匹配的catch块,那么,系统就会调用一个系统函数terminate,使程序终止运行。
4 try-catch应用
通过前面的学习,我们掌握了try-catch捕获异常的基本方法。但是,C++提供的异常处理机制很完善,可以考虑多种异常的情况。那么,可以总结如下:
(1) 一个函数可以throw抛出多个异常,try-catch可以使用多个catch捕获不同类型的异常。
程序测试代码如下:
程序运行结果如下:
可以看到,在add()函数中throw多个异常信息。然后,在try后面有2个catch语句块。当执行t.add(11)的时候,就在add()函数中执行 throw 12689;语句,抛出12689消息。
此时,马上结束try中的语句块,不再执行接下来的t.add(16);等语句。直接跳转到catch()语句块中。
此时,抛出的12689消息是一个int类型的数值,所以,提交给catch(int e)捕获,捕获一个int类型的消息。
在进行异常处理后,程序并不会自动终止,继续执行catch子句后面的语句。
来源地址:https://blog.csdn.net/feng19870412/article/details/128977250