目录
异常处理机制有两个主要成分:
①.异常的鉴定与发出
②.异常的处理方式
异常出现之后,正常程序的执行便被暂停。与此同时,异常处理机制开始搜索程序中有能力处理这一异常的地点。异常被处理完毕之后,程序的执行便会继续,从异常处理点接着执行下去。
eg:
try
{
throw "GodFishhh"; //抛出异常
}
catch("GodFishhh")
{
//处理异常
}
//异常处理结束处
return false;
在经过throw抛出异常和catch接受异常后,程序从异常处理点的下方继续执行下去,而上述代码段则执行语句:return false;
一.抛出异常
1.C++通过throw表达式产生异常。
2.throw 语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出的异常的类型。
throw 42; //异常类型为整数
throw "GodFishhh" //异常类型为字符串
抛出类对象异常:
throw iterator_overflow(_index,_max_elems_);
上述语段其实是调用了iterator_overflow类的构造函数创建了一个iterator_overflow对象再由throw抛出,如下:
iterator_overflow ex(_index,_max_elems_);
throw ex;
单独使用throw:
catch(iterator_overflow &iof)
{
....
throw;
}
此种用法只能在catch中出现,其作用是再次抛出此catch所捕获的异常。
二.捕获异常
1.C++通过单条或者一连串catch子句来捕获被抛出的异常。
catch的语法:
catch(ExceptionName Parameter)
{
//处理异常
}
其中小括号内为异常要传入的参数,大括号内为处理异常的方法。
eg:
catch(int &sortfail)
{
...
}
catch(string ®isterFail)
{
...
}
若想通过一条catch语句处理所有的异常类型:
catch(...)
{
//处理异常
}
则在catch的小括号中指定省略号"..."即可。
2.catch子句一般放在try块的末尾,try块是以关键字try作为开始,然后是大括号内的一连串程序语句。
try
{
...
}
catch(ExceptionName Parameter)
{
...
}
这表示如果try块内有任何异常发生,便由接下来的catch子句加以处理。
三.提炼异常
提炼顺序:
①.在抛出异常后,程序则会跳转到相匹配的catch语句中处理异常。
②.若是try块中出现的异常,则由try块下的catch子句来处理异常。
③.若不是try块中出现的异常,则异常处理机制会在异常出现处的调用端搜寻吻合的catch子句。
④.“函数调用链”不断被解开,如果一直回到main()函数中还是找不到合适的catch子句,程序便会调用标准库提供的terminate()函数,其默认是中断整个程序的执行。
四.C++标准异常
1.C++ 提供了一系列标准的异常,定义在 <exception> 中,我们可以在程序中使用这些标准的异常。
它们以抽象基类和派生类的结构组织起来:
上述异常说明:
2. 我们可以将自己编写的类继承于抽象基类exception之下(必须提供虚函数what()的定义)
虚函数what():
virtual const char* what()const;
what是定义在抽象基类exception中的一个虚函数,其返回一个const char*,通常用来返回异常出现的原因。
将类继承于excepction之下:
#include<exception>
#include<iostream>
using namespace std;
class GodFishhh:public exception
{
public:
const char* what() const
}
const char* GodFishhh() const
{
cerr<<"GpdFishhh wrong"<<endl;
}
通过cerr输出可以不经缓冲直接输出,一般用于输出错误信息。
异常捕获:
try
{
throw GodFishhh; //抛出一个exception类的派生类(调用默认构造函数)
}
catch(const exception& ex) //参数为基类的引用,传入的实参可以是基类所有派生类
{
cerr<<ex.what()<<endl;
}
上述语段可以捕获所有exception派生类的异常,并输出异常产生的原因。(通过调用对应类的what函数来返回一段const char*字符串)