16.2.7 标准异常
头文件<exception>中定义了exception标准异常类,可用它作为其他异常类的基类。头文件<stdexcept>中定义了其他几个异常类,主要有logic_error和runtime_error两个,它们都是从exception类public派生而来。
logic_error用于描述程序中出现的逻辑错误,如传递无效的参数等,一般可通过编程修复。runtime_error描述了可能在运行期间发生但难以预料的错误,例如硬件故障或者内存耗尽,这种异常一般无法避免,会导致程序失败。logic_error和runtime_error都提供了一个参数类型为std:string的构造函数,这样就可以把消息保存到这两种类型的异常对象中,通过exception:what成员函数,可以从对象中得到它所保存的信息,what函数的原型如下所示。
virtual const char*what();
如果自定义的类从exception类派生而来,通过定义虚成员函数what可返回一个字符串,指示异常信息。
在logic_error和runtime_error两个类的基础上,派生了其他几个标准异常类,供函数抛出,用以细分可能出现的情况,如表16.1所示。
因为exception类是上述所有异常类的基类,所以一个快捷的办法就是使用基类的对象作为catch块的参数,来捕获所有的标准异常类异常,如代码16.9所示。
代码16.9 标准异常类的使用ExceptionSample
<———————————-文件名:example1609.cpp———————————————> 01 #include<stdexcept>//必须的头文件 02 #include<iostream> 03 using namespace std; 04 void fun(int x) 05 { 06 if(x<0) 07 throw invalid_argument("参数传递错误");//抛出了标准异常类对象 08 } 09 int main() 10 { 11 try 12 { 13 fun(-3); 14 } 15 catch(exception&e)//使用基类(exception类)捕获所有派生类异常 16 { 17 cout<<e. what()<<endl; 18 } 19 return 0; 20 }
输出结果如下所示。
参数传递错误
【代码解析】代码第7行的fun函数中抛出了invalid_argument标准异常类对象,在main函数中,只使用参数为exception类对象的catch块便可以捕获所有直接派生和间接派生自exception的异常。
从exception中还可以派生由于C++语言特性而抛出的异常,例如new抛出bad_alloc、dynamic_cast抛出bad_cast以及typeid抛出bad_typeid。先来看一下关于new运算符的处理,其他两个将在RTTI一章中进行介绍。
在使用运算符new申请动态内存时,有可能会失败。之前讲过如果内存未申请成功,返回的指针为null空指针,通过判断返回指针是否为空可进行防错处理。实际上,头文件<new>中声明了bad_alloc异常类,同样是从exception类public派生而来的,注意bad_alloc类对象是由new运算符自动抛出的,如下所示。
try { int*p=new int[1000]; } catch(bad_alloc&ba) { //当上述try块中内存申请失败时,异常被捕获 }
若try块中动态内存申请失败,bad_alloc异常类对象将会被自动抛出,由相应的catch函数捕获并进行处理。