首页 理论教育 大道至简:C++STL类exception

大道至简:C++STL类exception

时间:2023-10-25 理论教育 版权反馈
【摘要】:在STL中,类exception除了构造函数和析构函数之外,仅有一个虚成员what()函数。类exception的声明形式如下:在上述类声明中,其3个构造函数和1个析构函数均被设置了空抛出。例如,如果使用类std::exception处理派生的异常,可以在同一个基类处理程序中捕获此类信息。STL定义了很多基于类exception的异常类型。异常类runtime_error描述了可能在运行期间难以预计和防范的错误。头文件<new>中包含了bad_alloc类型声明,它是从异常类exception派生而来的。

大道至简:C++STL类exception

在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,尝试了各种错误类别的抛出和捕获。请读者认真体会,理解它们的用法。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈