(*^-^ *)
没有rethrow哟
异常处理的方向:由下向上,异常超脱于函数机制,决定了其对函数的跨越式回跳
函数调用的方向:由上到下
异常处理语句
⚫将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执
行到达try语句,然后执行try块内的保护段。
⚫ 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子
句就不执行。程序从try块后跟随的最后一个catch子句后面的语句
继续执行下去。
⚫ catch子句按其在try块后出现的顺序被检查。匹配的catch子句将
捕获并处理异常(或继续抛掷异常)。
⚫ 可以只有try块而无catch块
表达式可以是对象或整数
catch语句:
当没有指定的异常信息的类型时,可以使用省略号
catch(…) {cout<<“OK”<<endl;}
e.g.除0异常
#include<iostream>
using namespace std;
double divide(double x, double y)
{
if (y == 0)
{
throw x;//数据被传递到catch语句中
}
return x / y;
}
int main()
{
try
{
cout << "6/2=" << divide(6, 2) << endl;
cout << "8/0=" << divide(8, 0) << endl;//数据在函数中被传递到catch语句中,后面try块中的语句不再执行
cout << "7/1=" << divide(7, 1) << endl;//抛出之后的语句不再执行
}
catch (double x)
{
cout <<x<< " is divided by 0" << endl;
}
cout << "operator finish" << endl;//catch语句块执行完成后,后面的语句按照顺序依然执行
}
修改,若果想要异常语句之后的语句能够继续执行:
try
{ cout<<"5/2="<<Div(5,2)<<endl; }
catch(int)
{ cout<<"except of deviding zero.\n"; }
try//异常之后在catch之后,可以继续执行
{ cout<<"8/0="<<Div(8,0)<<endl; }
catch(int)
{ cout<<"except of deviding zero.\n"; }
try
{ cout<<"7/1="<<Div(7,1)<<endl;}
catch(int)
{ cout<<"except of deviding zero.\n"; }
e.g.文件打不开异常
#include <fstream>
#include <iostream>
using namespace std;
int main () {
ifstream source (“a.txt”); //打开文件
char line[128];
try {
if (source.fail())
throw “a.txt” ;
}
catch (char * s) {
cout << "error opening the file " << s << endl;
exit(1);
}
while ( !source.eof()) //注意判断文件输入结束的语句
{
source.getline (line, sizeof(line)) ;//getline需要写清读入的字节长度
cout << line << endl ;
}
source.close() ;
return 0; }
异常接口声明
函数事先声明可能抛出的异常,声明之后函数可以抛出的异常类型将受到限制,没有声明就可以抛出任何类型的异常,但如果throw的表达式为空,就说明函数不抛掷任何类型的异常。
异常处理的构造与析构
e.g.try 语句块中有类的对象
先构造局部对象,如果有错误,在throw之前将这个局部对象析构
#include <iostream>
using namespace std;
void MyFunc(void);
class Expt
{
public:
Expt() { cout << "cons for Expt" << endl; }
~Expt() { cout << "des for Expt" << endl; }
const char * ShowReason() const
{ return "Expt类异常。"; }
};class Demo
{ public:
Demo();
~Demo();
};
Demo::Demo()
{
cout<<"构造 Demo."<<endl;
}
Demo::~Demo()
{
cout<<"析构 Demo."<<endl;
}
void MyFunc()
{ Demo D;
cout<<"在MyFunc()中抛掷Expt类异常。"<<endl;
throw Expt();
}
17int main()
{ cout<<"在main函数中。"<<endl;
try
{ cout<<"在try块中,调用MyFunc()。" <<endl;
MyFunc();
}
catch( Expt E )
{ cout<<"在catch异常处理程序中。“;
cout<<endl;
cout<<"捕获到Expt类型异常:";
cout<<E.ShowReason()<<endl;
}
catch( char *str )
{ cout<<"捕获到其它的异常:"<<str<<endl; }
cout<<"回到main函数。从这里恢复执行。" <<endl;
return 0;
}
输出:
在main函数中。
在try块中,调用MyFunc()。
构造 Demo.
在MyFunc()中抛掷Expt类异常。
cons for Expt 在throw时,局部变量不析构掉
析构 Demo.
在catch异常处理程序中。
捕获到Expt类型异常:Expt类异常。
des for Expt 执行完catch语句才进行析构
des for Expt
回到main函数。从这里恢复执行。
标准程序库的异常类
exception 标准程序库异常类的公共基类
logic_error 可以被预先检测到的异常
runtime_error难以被预先检测到的异常