C++异常处理
Try
Throw
Catch
如果某段程序中发现了自己不能处理的异常,可以使用Throw表达式来抛掷这个异常。
Try子句后的复合语句是代码段的保护。如果预料到某段代码可能发生异常,就将其放在Try子句之后。如果遇到异常,则其中的Throw表达式就会抛出这个异常。
执行过程:
- 程序正常执行到Try语句,然后执行其中的代码。
- 如果在保护段内执行期间没有引起异常,那么跟在Try之后的Catch子句就不执行。程序从异常被抛掷的Try块后跟随的最后一个Catch子句后面的语句执行下去。
- 程序执行到一个Throw表达式时,一个异常对象会被创建。若异常的抛出点本身就在一个Try子句内,则该Try语句后的Catch子句会按顺序检查异常类型是否与声明的类型匹配;若异常被抛出点本身不在任何Try子句内,或抛出的异常与各个Catch子句声明的类型皆不匹配,则结束当前函数的执行,回到当前函数的调用点,把调用点作为异常的抛出点,然后重复这一过程。直到异常被一个Catch语句捕获。
- 如果始终未找到与被抛掷异常匹配的Catch子句,最终Main函数会停止执行。
- 如果找到了一个匹配的Catch子句,则Catch子句后的复合语句会执行。复合语句执行完毕之后,当前Try块即执行完毕。
Trhow与Catch匹配:
- catch子句中声明的异常类型就是抛出异常对象的类型或者是引用。
- catch子句中声明的异常类型是抛出异常对象的的类型的公共基类或其引用。
- 抛出异常类似和catch子句中声明的异常类型皆为指针类型,且前者到后者可以隐式转换。
- catch(. . .)可以匹配所有异常。
#include <iostream>
using namespace std;
int divide(int x,int y)
{
if(y==0)
throw x;
return x/y;
}
int main()
{
try
{
cout<<"5/2="<<divide(5,2)<<endl;
cout<<"8/0="<<divide(8,0)<<endl;
cout<<"7/1="<<divide(7,1)<<endl;
}
catch (int e)
{
cout<<"Error "<<e<<" is divided by zero!"<<endl;
}
cout<<"That's Ok"<<endl;
return 0;
}
输出:
5/2=2
Error 8 is divided by zero!
That's Ok
强大功能:具有为异常抛掷前构造的所有局部对象自动调用析构函数的能力!
用一个不带操作数的Throw 表达式可以将当前正在被处理的异常再次抛出,这样一个表达式只能出现在一个Catch子句中或者在Catch子句内部调用的函数中。