学科分类
目录
C++基础

标准库中的异常处理

C++标准库提供了标准异常层次,该层次中提供了异常基类exception,程序抛出的所有异常都派生自该基类,异常基类及派生类构成了如图1所示的层次关系。

图1 C++标准异常类层次结构

基类exception定义在头文件exception中,它的接口如下所示:

class exception{
public:
     exception() throw();
     exception(const exception &) throw();
     exception &operator=(const exception &) throw();
     virtual ~exception() throw();
     virtual const char * what() const throw();
};

exception类接口中的函数都有一个空的异常规范throw(),这表示exception类成员函数不会抛出任何异常。成员函数what()返回一个字符串,它描述抛出异常的相关信息。what()是一个虚函数,exception类的派生类可以重新定义what()函数,以便更好地描述派生类的异常对象。

从基类exception可以直接派生出runtime_error和logic_error,每个派生类又可以派生其他类。所有这些标准异常类可分为三组:

1、语言本身支持的异常:此类异常用以支持某些语言特性。

● new操作失败,会抛出bad_alloc异常。

● 程序执行期间,若动态类型转换操作失败,dynamic_cast会抛出bad_cast异常。

● 在执行类型辨别的过程中,若交给typeid的参数为零或空指针,typeid操作符会抛出bad_typei异常。

● 若发生意外异常(函数抛出异常规格(exception specification)以外的异常),通过在函数的异常抛出表中添加std::bad_exception,会调用unexpected()抛出bad_exception异常,而不是终止程序或调用set_unexception指定的函数。

2、 C++标准程序库发出的异常:C++标准程序库异常总是派生自logic_error。

● invalid_argument表示无效参数。

● length_error指长度超过所操作对象允许的最大允许长度。

● out_of_range表示数组或下标之类的数值超过了界定的范围。

● domain_error指出非法预处理错误。

此外,标准程序库的IO部分提供一个名为ios_base::failure的特殊异常,当数据流由于错误或者到达文件末尾而发生状态改变时,就可能抛出这个异常。

3、 程序作用域之外发生的异常。

派生自runtime_error的异常,表示程序中只能在执行时发生的错误。

● range_error指出内部计算时发生区间错误。

● overflow_error指算术运算时发生上溢。

● underflow_error指算术运算时发生下溢。

为了使用异常类,需要包含相应的头文件。bad_exception定义于<exception>。bad_alloc定义于<new>。bad_cast和bad_typeid定义于<typeinfo>。ios_base::failure定义于<ios>。其他异常类别定义于<stdexcept>。

runtime_error和logic_error是一些具体的异常类的基类,它们表示两大类异常。logic_error表示那些可以在程序中被预先检测到的异常,若编写程序时比较小心,则该类异常可以避免。runtime_error则表示难以被预先检测的异常。这两个类及派生类均有一个接收“const string &”型参数的构造函数,构造异常对象时,可以将错误信息传递给该函数,之后通过调用该对象的what()函数,可以得到构造时提供的异常信息。

接下来通过一个案例来学习如何使用标准库中logic_error派生类invalid_argument进行异常处理,如例1所示。

例1

 1    #include <iostream>
 2    #include <stdexcept>
 3    using namespace std;
 4    
 5    int set_age(int age)
 6    {
 7        if (age <= 0)//若年龄值不符合实际情况,则抛出invalid_argument异常类对象
 8            throw invalid_argument("The age should be greater than 0!");
 9        return age;
 10    }
 11    
 12    int main()
 13    {
 14        int age;
 15        try{
 16            age = set_age(0);
 17        }
 18        catch (exception &e)
 19        {
 20            cout << "Exception:" << e.what() << endl;
 21        }
 22        system("pause");
 23        return 0;
 24    }

程序运行结果如图2所示。

图2 例1运行结果

例1中年龄值异常时抛出invalid_argument类异常,并在构造异常对象时提供异常信息,在main()函数的catch结构中通过调用what()函数显示了异常内容。

点击此处
隐藏目录