其他异常特型
(一些碎碎念
虽然throw-catch机制类似于函数参数和返回机制,但还是有所不同. 其一便是函数中的返回语句是将控制权返回到调用函数的函数,但throw语句将向上寻找,并将控制权返回给一个能够捕获相应异常的try-catch组合.
另一个不同便是,引发异常是编译器总是创建一个临时拷贝.举个栗子:
对于接在函数名后面的throw(something):
void fun() throw(); //表示fun函数不允许抛出任何异常,即fun函数是异常安全的
void fun() throw(…); //表示fun函数可以抛出任何形式的异常
void fun() throw(exceptionType); // 表示fun函数只能抛出exceptionType类型的异常
使用引用传递参数更重要的原因是,基类可以使用派生类对象.现在假设有个异常类层次结构,冰妖分别处理不同的异常类型,则使用基类引用能够捕获任何异常对象;而使用派生类对象则只能捕获他所属类以及他的派生类的对象.
因为基类可以使会用派生类对象,而且引发异常的对象将被第一个与之匹配的catch块捕获,那么所以catch块的排列顺序应该与派生类顺序相反:这又是一个一不留神就会留下bug的功能
如果将catch(bad_1 & b1)
放在最前面,他将捕获 bad_1,bad_2,bad_3, 只能通过相反的顺序排列,bad_3才会被bad_3处理程序所捕获.
所以说,如果有一个异常类继承层次结构,应该这样排列catch块: 将捕获位于层次结构最下面的异常类的catch语句放在最前面,将捕获基类异常的catch语句放在最后面;
也就是倒着写
exception类
exception头文件定义了exception类,C++可以把它用作于其他异常类的基类.使代码可以引发exception异常,他有一个名曰what()的虚方法,因为是个虚方法所以你可以根据你的实现重定义他.
|
|
当然你也可以分开捕获他们,去吧大师球
1.stdexcept异常类
头文件sedexcept定义了几个异常类.比如logic_error和runtime_error类,他们都是以公有集成的方式从exception类继承过来的:
这两个新的类又被作为两个派生类系列的基类,其中logic_error类描述了典型的逻辑错误,这些逻辑错误是可以通过合理编程避免的,但还是可能发生.
下面每个类的名称指出了他们用于报告的错误类型:
logic_error类:
- domain_error:
- invalid_argument:
- length_error
- out_of_bounds:
doormain_error:
数学函数值域(range)和定义域(domain),定义域由函数可能的参数组成,值域由函数可能的返回值组成,函数在输入参数或返回值不在制定范围的情况下将会引发domain_error异常;
incalid_argument:
异常incalid_argument指出了给函数传递了一个意料之外的值.这个和定义域(domain)都有点不一样.例如如果希望输入的每个字符串要么是0要么是1,那么当输入的字符串中包含其他字符的时候,incalid_argument会被触发.
length_error:
异常length_error指出了由于没有足够的空间类执行所需操作.比如string类的append()方法在合并得到的字符串长度超了的时候;
out_of_bounds:
异常out_of_bounds通常用于指示索引错误,比如定义了个数组类,其operator()[]在使用的索引无效时引发out_of_bounds异常
runtime_error类
这个类描述了可能在运行期间发生的难以预料的错误:
- range_error:
- overflow_error:
- underflow_error:
下溢(underflow)
存在浮点类型可以表示的最小非零值,当计算结果小于这个值的时候,将导致下溢错误.
上溢(overflow)
存在计算结果超过了某种类型能够表示的最大数值时,将导致上溢.
对于计算结果可能不在函数允许范围之内,但没有发生上下溢的时候可以用range_error异常;
继承关系可以使程序员一起处理他们(如果你愿意的话):
下面代码分别处理每种异常,先单独捕获out_of_bounds,然后统一不过其他logic_error系列异常,最后统一不过exception异常,runtime_error,以及其他从exception派生而来的异常:
bad_alloc异常和new
对于使用new导致的内存分配问题,C++比较新的处理方式是让new引发bad_alloc异常,头文件new包含bad_alloc的声明.他是从exception类公有派生而来,但在以前当无法分配请求的内存量时new返回一个空指针.
举个栗子:
如果内存申请失败了则方法what()将会返回字符串std::bad_alloc.(在我的MinGW5.5下返回std::bad_array_new_length)如果你的程序没触发异常清加大请求分配内存量
另外还有一种是在new处理失败时返回空指针的: