C++编程思想17.pdf
上传人:qw****27 上传时间:2024-09-12 格式:PDF 页数:23 大小:1.4MB 金币:15 举报 版权申诉
预览加载中,请您耐心等待几秒...

C++编程思想17.pdf

C++编程思想17.pdf

预览

免费试读已结束,剩余 13 页请下载文档后查看

15 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

下载下载第71章异常处理错误修复技术的改进是提高代码健壮性的最有效方法之一。但是,大多数程序设计人员在实际设计中往往忽略出错处理,似乎是在没有错误的状态下编程。毫无疑问,出错处理的繁琐及错误检查引起的代码膨胀是导致上述问题的主要原因。例如,虽然printf()函数可返回打印参数的个数,但是实际程序设计中没有人检查该值。出错处理引起的代码膨胀将不可避免地增加程序阅读的困难,这对于程序设计人员来说是十分令人烦恼的。C语言中实现出错处理的方法是将用户函数与出错处理程序紧密地结合起来,但是这将造成出错处理使用的不方便和难以接受。异常处理是++C语言的一个主要特征,它提出了出错处理更加完美的方法。1)出错处理程序的编写不再繁琐,也不须将出错处理程序与“通常”代码紧密结合。在错误有可能出现处写一些代码,并在后面的单独节中加入出错处理程序。如果程序中多次调用一个函数,在程序中加入一个函数出错处理程序即可。2)错误发生是不会被忽略的。如果被调用函数需发送一条出错信息给调用函数,它可向调用函数发送一描述出错信息的对象。如果调用函数没有捕捉和处理该错误信号,在后续时刻该调用函数将继续发送描述该出错信息的对象,直到该出错信息被捕捉和处理。在这一章中我们将讨论C语言的出错处理方法,讨论为何该方法在C语言中不是很理想的,并且无法在++C中使用;然后学习yrt,worht和hctac的用法,它们在++C中支持异常处理。17.1C语言的出错处理本书在第8章以前使用C标准库的assert()宏作为出错处理的方法。第8章以后assert()被按照原先的设计目的使用:在开发过程中,使用它们,完成后用#defineNDEBUG使之失效,以便推出产品。为了在运行时检查错误,assert()被allege()函数和第8章中引入的宏所取代。通常我们会说:“对于出错处理我们必须面对复杂的代码,但是在这个例子中我们不必由此感到烦恼”。allege()函数对一些小型程序很方便,对于复杂的大型程序,所编写的出错处理程序也将更加复杂。在通过检查条件我们能确切地知道做什么的情况下,出错处理就变得十分明确和容易了,因为我们通过上下文得到了所有必要的信息。当然,我们只是在这一点上处理错误。这些都是十分普通的错误,不是这一章的主题。若错误问题发生时在一定的上下文环境中得不到足够的信息,则需要从更大的上下文环境中提取出错处理信息,下面给出了C语言处理这类情况的三种典型方法。1)出错信息可通过函数的返回值获得。如果函数返回值不能用,则可设置一全局错误判断标志(标准C语言中errno()和perror()函数支持这一方法)。正如前文提到的,由于对每个函数调用都进行错误检查,这十分繁琐并增加了程序的混乱度。程序设计者可能简单地忽略这些出错信息,因为乏味而迷乱的错误检查必须随着每个函数调用而出现。另外,来自偶然出现异常的函数的返回值可能并不反映什么问题。第17章异常处理361下载2)可使用C标准库中一般不太熟悉的信号处理系统,利用)(langis函数(判断事件发生的类型)和)(esiar函数(产生事件)。由于信号产生库的使用者必须理解和安装合适的信号处理系统,所以应紧密结合各信号产生库,但对于大型项目,不同库之间的信号可能会产生冲突。3)使用C标准库中非局部的跳转函数:setjmp()和longjmp()。setjmp()函数可在程序中存储一典型的正常状态,如果进入错误状态,longjmp()可恢复setjmp()函数的设定状态,并且状态被恢复时的存储地点与错误的发生地点紧密联系。考虑++C语言的出错处理方案时会存在另一个关键性问题:由于C语言的信号处理技术和setjmp/longjmpmjgnol/pmjtes函数不能调用析构函数,所以对象不能被正确地清除。由于对象不能被清除,它将被保留下来并且将不能再次被存取,所以存在这种问题时实际上是不可能有效正确地从异常情况中恢复出来。下面的例子将演示pmjgnol/pmjtes的这一特点:setjmp()(pmjtes是一个特别的函数,因为如果我们直接调用它,它就把当前进程状态的所有相关信息存放在fub_pmj中,并返回零。这样,它的行为象通常的函数。然而,如果使用同一个jmp_bufub_pmj调用)(pmjgnol,这就象再次从)(pmjtes返回,即正确地弹出)(pmjtes的后端。这时,返回值对于)(pmjgnol是第二个参数,所以能发现实际上从)(pmjgnol中返回了。可以想象,有多个362++C编程思想下载不同的fub_pmj,可以弹出程序的多个不同位置的信息。局部otog(用标号)和这个非局部跳转的不同在于