5.3 异常处理
异常是指程序运行时出现的非正常的情况,如访问指针地址无效、除零错误等。为了防止程序因出现异常而中断,C++语言提供了异常处理语句,使用户有机会对出现的异常进行处理,增强程序的健壮性。本节将介绍有关C++语言异常处理的相关知识。
5.3.1 异常捕捉语句
在C++语言中,为了处理异常,提供了try语句和catch语句。try语句和catch语句实际上是两个语句块,try语句块包含的是可能产生异常的代码,catch语句块包含的是处理异常的代码。下面编写一段代码,演示try语句和catch语句的使用。
【例5.44】 编写异常捕捉语句。(实例位置:资源包\TM\sl\5\22)
执行上述代码,结果如图5.22所示。
上述代码有意产生一个除零的错误,使用try语句捕捉可能产生的异常,使用catch语句处理产生的异常。实际上,如果用户不处理异常,系统会进行默认的处理,但是这通常会导致程序的终止。例如,上述代码如果去除try语句和catch语句,将会终止程序,并出现如图5.23所示的错误。
图5.22 除零错误
图5.23 系统错误信息
通过在程序中使用try和catch语句,用户可以截获可能产生的异常并进行处理,这样可以避免系统进行默认处理,防止了由于异常而导致程序的终止。
在try语句中,如果当前代码产生了异常,则try语句中其后的代码将不会执行,程序直接跳转到catch语句中。在上述的代码中,“int ret=x/y;”语句引发了除零的异常,程序将执行catch语句中的“printf("除法运算错误!\n");”语句,而不会再执行try语句中的“printf("执行除法运算!\n");”语句,因此出现了如图5.22所示的结果。
在catch语句中出现了“…”符号,表示处理所有异常。如果try语句中没有产生异常,则不会执行catch语句中的代码。实际上一个try语句可以对应多个catch语句,每一个catch语句可以关联一个异常类,当try语句中产生的异常与catch语句关联的异常匹配时,将执行该catch语句中的代码。
注意
try部分的语句是可能出现错误的语句,该语句必须由大括号包含,即使只有一条语句。catch部分的语句是处理异常的语句,该部分语句也必须由大括号包含。在try程序段后,必须紧跟一个或多个catch程序段,这是C++语法所要求的。每个catch程序段用于捕获一种类型的异常,并列的catch程序段之间不允许插入其他语句。
5.3.2 抛出异常
异常不仅可以由系统触发(代码违规产生的异常),也可以由用户触发。C++语句提供了throw关键字,用于手动触发异常。对于用户触发的异常,其好处是用户能够定义自己的逻辑规则。例如:
在上述代码中,用户定义了自己的一个除法规则,即如果除数为负数,将触发异常,执行catch语句块中的代码。
在程序中,throw语句通常出现在try语句块中。当程序中出现throw语句时,其后的代码将不会执行,跳转到catch语句块中。因此,上述代码中的“int ret=x/y;”语句和“printf("执行除法运算!\n");”语句不会被执行。下面编写一个除法函数,演示如何自定义异常和触发异常。
【例5.45】 自定义异常类。(实例位置:资源包\TM\sl\5\23)
下面调用Div函数,将除数设置为负数,使其触发自定义的异常。代码如下:
执行上述代码,结果如图5.24所示。
图5.24 自定义异常
从图5.24中可以发现,语句“Div(20,-5,ret);”触发了自定义的异常CNegException。