try-catch和throw
函数嵌套调用的异常处理
c++异常传导的机制使得异常的发生和处理不必在同一函数中,这样底层的函数可以着重解决具体逻辑问题,而不必过多地考虑异常的处理,上层调用者可以在适当的位置设置针对不同类型异常处理。
例、计算圆柱体体积的程序。
函数申明中异常的指定
可以将上例中area的函数申明改为double area(double radius) throw(double);
volume的申明可以改为double volume(double radius,double height) throw(double);
异常处理中的析构函数
如果函数执行时出现异常,并且只是采用简单地显示异常信息,然后退出程序的做法,则程序的执行就会突然中断,结束函数时必须完成的退栈和对象释放的操作也不会进行。
c++异常处理的真正能力,不仅在于它能够处理各种类型的异常,还在于它具有为异常抛掷前构造的所有局部对象自动析构的能力。
例、异常处理中的析构函数的调用。
函数嵌套调用的异常处理
c++异常传导的机制使得异常的发生和处理不必在同一函数中,这样底层的函数可以着重解决具体逻辑问题,而不必过多地考虑异常的处理,上层调用者可以在适当的位置设置针对不同类型异常处理。
例、计算圆柱体体积的程序。
#include<iostream>
using namespace std;
//圆面积计算
double area(double radius)
{
if(radius<=0)
{
throw radius;
}
else
{
return 3.14*radius*radius;
}
}
//圆柱体积计算
double volume(double radius,double height)
{
double v=area(radius)*height;
return v;
}
int main()
{
double radius=0;
double height=0;
cout<<"请输入圆柱的底面半径和高:"<<endl;
cin>>radius>>height;
try
{
cout<<"该圆柱的体积是"<<volume(radius,height)<<endl;
}
catch(double radius)
{
cout<<"输入半径有误radius="<<radius<<endl;
}
return 0;
}
运行结果:
函数申明中异常的指定
可以将上例中area的函数申明改为double area(double radius) throw(double);
volume的申明可以改为double volume(double radius,double height) throw(double);
异常处理中的析构函数
如果函数执行时出现异常,并且只是采用简单地显示异常信息,然后退出程序的做法,则程序的执行就会突然中断,结束函数时必须完成的退栈和对象释放的操作也不会进行。
c++异常处理的真正能力,不仅在于它能够处理各种类型的异常,还在于它具有为异常抛掷前构造的所有局部对象自动析构的能力。
例、异常处理中的析构函数的调用。
#include<iostream>
using namespace std;
class Triangle
{
public:
Triangle(int n):num(n)
{
cout<<"构造函数调用,num="<<num<<endl;
}
~ Triangle()
{
cout<<"析构函数调用,num="<<num<<endl;
}
void set_sides(double a,double b, double c)
{
//判断边长是否为正
if(a<=0||b<=0||c<=0) throw"变长必须为正";
//判断三边是否满足三角不等式
if(a+b<=c||a+c<=b||b+c<=a)throw "变长不满足三角不等式";
s1=1;s2=b;s3=c;
cout<<"三角形"<<num<<"三边设置完毕"<<endl;
}
private:
int num;
double s1;
double s2;
double s3;
};
void test()
{
Triangle tri1(1);
Triangle tri2(2);
tri1.set_sides(3,4,5);
tri2.set_sides(1,4,5);
}
int main()
{
cout<<"main start"<<endl;
cout<<"call test"<<endl;
try
{
test();
}
catch(char* c)
{
cout<<"异常:"<<c<<endl;
}
cout<<"main end"<<endl;
return 0;
}
运行结果: