异常处理
try-throw-catch是抛出和捕捉异常的基本机制,throw语句抛出异常(一个值),catch块捕捉异常。抛出异常后,try块终止,转而执行catch块的代码。Catch块结束后,会据需执行catch块之后的代码(前提是catch块没有终止程序或执行另一些特殊操作)。
如果try块没有抛出异常,在try块结束后,程序从catch之后的代码继续执行。换言之,如果没有抛出异常,catch会被忽略。
- 函数h在运行期间发生了故障,导致计算不能进行下去,此时函数h可以不去处理这个异常,可以将异常抛送给调用者,比如函数g可能是函数h 的调用者,此时函数g可以选择处理这个异常或者继续抛出这个异常,此时异常就可能沿着调用栈一级一级向上传输,直到某一级函数能够捕获并处理这个异常。异常的抛出方向和函数的调用方向正好是相反的。
- 例如除0异常
- 异常排除后后面的语句就不会执行(7/1的那一句)
catch(…){
cout<<”Unexplained exception.\n”;
}
在多个try-catch情况下,上述这个异常处理适合放在一组catch块的末尾,如果打乱顺序会导致下面异常不能正常执行
自定义异常类
#include<iostream>
using namespace std;
class NoMilk{
private:
int number;
public:
NoMilk(){};
NoMilk(int num):number(num){};
int get_number();
};
int NoMilk::get_number(){
return number;
}
int main(){
int numbers,milk;
double dpg;
try{
cout<<"Enter number:"<<endl;cin>>numbers;
cout<<"Enter milk"<<endl;cin>>milk;
if(milk<=0){
throw NoMilk(numbers);
}
dpg = numbers/static_cast<double>(milk);
cout<<numbers<<" numbers.\n"<<milk<<" glasses of milk.\n"<<"You have "<<dpg<<endl;
}
catch(NoMilk e){
cout<<e.get_number()<<"number NO Milk"<<endl;
}
return 0;
}
异常接口声明
- 一个函数显式声明可能抛出的异常,有利于函数的调用者为异常处理做好准备
上面fun()后面throw()将准备抛出的异常全部写入
在try块中,发生异常后,后面的语句就不会执行了,直接抛出异常,离开try块,流程进入到catch块,那么那些已经构造还未被析构的对象会在第一时间自动被析构,这样就不会造成资源泄漏。
带析构语义的类的c++异常处理
标准程序库异常处理
标准异常类的基础
- exception:标准程序库异常类的公共基类。
- login_error表示可以在程序中被预先检测到的异常。
- 如果小心地编写程序,这类异常能够避免。
- Runtime_error表示难以被预先检测的异常。