在STL中,类exception除了构造函数和析构函数之外,仅有一个虚成员what()函数。该函数用以获取“型别本身以外的附加信息”,其返回值是一个以null结束的字符串。类exception的声明形式如下:
在上述类声明中,其3个构造函数和1个析构函数均被设置了空抛出(throw())。其虚成员what()函数也被设置了空抛出。
what()函数返回的字符串可以被转换为wstring,以便于被显示。what()返回的C-string在所属的异常对象被摧毁后即不再有效。what()函数是唯一被用来描述异常种类的虚函数。唯一可能实现的另一种异常评估手段是根据异常的精确型别,自己得出结论。最简单的例子如下:
前面已经说过,C++异常的主要目的是为设计容错程序提供语言级支持,即异常使得在程序设计中包含错误处理功能更简便,避免事后采取“冷酷”的错误处理方式。异常灵活性和相对方便性可以使程序员在条件允许的情况下,在程序中加入错误处理功能。总而言之,异常是一种特性,类似于类,可以改变程序员的编程方式。
头文件<exception>中定义了异常类,C++可以将其作为其他异常类的基类。程序会引发异常(exception),但由于what()是虚函数,类exception派生的自定义类可以重新定义该函数。例如,
如果使用类std::exception处理派生的异常,可以在同一个基类处理程序中捕获此类信息。
当然也可以分别捕获这些异常(前面已有介绍)。
STL定义了很多基于类exception的异常类型。头文件<exception>提供了类bad_excep-tion,以供unexpected()函数使用。
1.异常类stdexcept
头文件<stdexcept>还定义了其他几个异常类。首先,该文件定义了类logic_error和类runtime_error,这两个类均是以公有方式从exception类派生而来的。类logic_error的声明形式如下:
该类的构造函数接受一个string型对象作为参数,该参数为what()函数提供了返回值(message.data)。
类runtime_error的声明形式如下:
同样,类runtime_error的构造函数也接受一个string型对象作为参数。该参数为what()函数提供了返回值(message.data)。
除上述两个类之外,还有类domain_error、类invalid_argument、类length_error和类out_of_range。这些类和类logic_error的情况非常类似。
对于类domain_error,数学函数通常有定义域和值域。定义域由参数的可能值组成,值域由函数可能的返回值组成。例如,如果程序员在开发程序时,将不合理的参数传递给std::sin()函数,会导致程序抛出domain_error类异常。
异常类invalid_argument用于提示“给函数传递一个意外的值”。例如,如果函数希望接受一个字符串,其中每个字符要么是0要么是1,那么当传递的字符串中包含其他字符时,该函数会引发类invalid_argument异常。
异常类length_error用于提示没有足够的空间来执行所需的操作。例如,类string的ap- pend()函数在合并获取的字符串长度超过最大允许长度时,会引发length_error异常。(www.xing528.com)
异常类out_of_range通常用于指示索引错误,即索引的数值超出了正常容量的上下限。例如,对于某数组,使用operator()[]进行访问时,若使用的索引无效,则会引发out_of_range异常。
异常类runtime_error描述了可能在运行期间难以预计和防范的错误。
每个类的名称均能显示出其报告的错误类型。例如,
每个类均有自己的构造函数。构造函数的参数用于虚what()函数返回的字符串。
下溢(Underflow)错误会出现在浮点数计算中。通常,存在浮点型可以表示的最小非零值,若计算结果比该值小,会导致下溢错误。整型和浮点型都可能发生上溢错误,当计算结果超出某种类型能够表示的最大数量级时,会导致上溢错误。当计算结果可能不在函数允许的范围内,但又没有发生上溢或下溢错误时,将引发range_error类型的异常。
通常,类logic_error的异常对象表明存在可以通过编程修复的问题;而类runtime_error的异常对象表明存在无法避免的问题。这些错误具有相同的常规特征,其区别在于:不同的类名能够让程序员分别处理每种异常。
捕获异常的形式是多种多样的。例如,
如果上述形式还不能满足需要,程序员需要从类logic_error或类runtime_error派生新类,以确保异常类被纳入同一个继承层次结构中。
2.bad_alloc异常和new()
对于使用new()时可能出现的内存分配问题,C++提供了两种可供选择的处理方式:①使new()在无法满足内存请求时返回空指针;②使new()引发bad_alloc类型异常。头文件<new>中包含了bad_alloc类型声明,它是从异常类exception派生而来的。在具体实现过程中,读者可根据实际情况选取一种方式,也可以使用编译器开关或其他方法。下面给出一个最简单的例题,说明异常被捕捉后,程序将显示what()函数返回的消息,之后终止运行。如果没有捕捉到异常,程序将继续执行,并查看返回值是否为空指针。
3.示例
针对上述内容,下面给出一个关于处理异常的简单例题。尽管在C语言中不建议使用goto语句,但为了便于测试各种异常类别,本例还是使用了两次goto语句。
例8-1
例8-1的执行结果为:
总结
例8-1测试了STL中所包含的各种异常派生类。通过反复地调用throw和catch,尝试了各种错误类别的抛出和捕获。请读者认真体会,理解它们的用法。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。