异常:是指在程序运行的过程中发生的一些异常事件(如:除0溢出,数组下标越界,所要 读取的文件不存在,空指针,内存不足,访问非法内存等等)。(异常是一个类。)异常处理就是处理程序中的错误。
基本思想:让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。即将问题检测和问题处理相分离。遇到错误 抛出异常 捕获异常。
c++异常机制相比C语言异常处理的优势:
涉及到三个关键字:try、catch、throw。
try/catch 语句的语法如下所示:
try
{
throw 异常值;
}
catch(异常类型1 异常值1)
{
处理异常的代码1;
}
catch(异常类型2 异常值2)
{
处理异常的代码2;
}
catch(...)//任何异常都捕获
{
处理异常的代码3;
}
具体案例:
若有异常则通过thow 操作创建一个异常对象并抛出。将可能抛出异常的程序段放到try块之中。catch子句会根据出现的先后顺序被检查,匹配的catch语句捕获并处理异常(或继续抛出异常),如果在try 段执行期间没有引起异常,那么跟在try后面的catch字句就不会执行。如果匹配的处理未找到,则运行函数terminate将自动被调用,其缺省功能调用abort终止程序。处理不了的异常,可以在 catch的最后一个分支,使用throw,向上抛。
以除法为例:
异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对 象,都会被自动析构。析构的顺序与构造的顺序相反,这一过程称为栈的解旋。
try
{
Data ob1;
Data ob2;
Data ob3;
throw 1;//抛出异常后 ob3 ob2 ob1依次自动析构(栈解旋)
}
案例说明:
异常的接口声明:函数声明可以捕获哪些类型的异常。
函数调用写在try语句中,有相应的捕获处理语句(catch)情况下:
捕获情况:
编写异常类:
class MyException//异常类
{
public:
MyException(){
cout << "异常变量构造" << endl;
};
MyException(const MyException & e)
{
cout << "拷贝构造" << endl;
}
~MyException()
{
cout << "异常变量析构" << endl;
}
};
两次构造析构
有delete释放,一次构造析构
不需要delete,一次构造析构
父类引用 可以捕获搭配该父类派生出的所有子类的子类
C++ 提供了一系列标准的异常,定义在 <exception> 中,我们可以在程序中使用这些标准的异常。它们是以父子类层次结构组织起来的
每个异常的说明:
编写自己的异常要基于标准异常,从exception上继承。