C++中的异常处理

#include <iostream.h>
#include <stdlib.h>

//【例15.1】编写一个除法函数Div,要求避免除数为零的情况。
//方法一:按照传统处理除数为零的问题,需先判断除数是否为零,若为零告警出错;非零做除法运算,返回结果。

double Div(double a,double b)
{ 
 if (b==0) //除数b为零,出错告警中断
 { 
  cout<<"Error:attempted to divid by zero!\n";
  exit(1); 
 }
 else return a/b; //除数b为非零,正常返回除法运算结果
}
void main15_1_1()
{ 
 cout<<"8.4/2.1="<<Div(8.4,2.1)<<endl;
 cout<<"8.4/0.0="<<Div(8.4,0.0)<<endl;
 cout<<"8.4/3.1="<<Div(8.4,3.1)<<endl;
}

//方法二:利用C++中提供的异常机制来处理除数为零的问题

double Div1(double a,double b)
{ 
 if (b==0) throw b; //发现异常,抛出异常对象b
  return a/b; 
}

void main15_1_2()
{ 
 try { 
   cout<<"8.4/2.1="<<Div1(8.4,2.1)<<endl;
   cout<<"8.4/0.0="<<Div1(8.4,0.0)<<endl;
   cout<<"8.4/3.1="<<Div1(8.4,3.1)<<endl;
 }
 catch(double) //异常处理程序
 { 
  cout<<"Error:attempted to divid by zero!\n";
 }
}

//【例15.2】定义一个Vector类,它可以用异常来处理下标越界的错误。

class Vector 
{
 int *p; //p为Vector向量指针
 int sz; //sz为Vector向量元素的大小
public:
 Vector(int size)
 {
  p=new int[size];
  sz=size;
 }
 ~Vector()
 { delete[]p; }
 int size() {return sz;}
 class Range{}; //下标越界异常类
 int& operator[](int i)
 { 
  if (i>=0&&i<sz) return p[i];
  throw Range(); //下标越界抛出Range()类型的异常对象
 }
};
//在Vector类内定义了一个空类Range,用它来生成Vector的异常对象表示下标越界。
//在重载下标运算符函数中,当检测到下标运算符越界时,用throw Range()抛出Range 
//类型的异常对象。

void f(Vector& v)
{
 try { //检测下标越界异常
       v[0]=1;
      v[v.size()+5]=10; //下标越界的错误
      cout<<"Try block end."<<endl;
 }
 catch(Vector::Range){ //下标越界异常处理
     cout<<"Vector::out of range!"<<endl;
 }
 cout<<"Function f() end."<<endl;
}

void main15_2()
{ 
 Vector vv(5);
 f(vv);
}

//【例15.3】 自定义一个基类,并从该基类公有派生两个不同派生类,实现对各种不同类型的捕获后的异常处理。

class Base
{
public:
 Base(){ };
};
class Derive1:public Base
{
public:
 int s;
 Derive1(int ss)
 { s=ss; }
};

class Derive2:public Base
{
public:
 Derive2(){ };
};

void fun()
{ 
 Derive1 Li(0); //定义一个Derive1类的对象Li
 int i,k=6;
 for (i=0;i<=k;i++)
 {
       try{
   switch(i){ 
    case 0: throw 10; //抛出int型异常
    case 1: throw 10.5; //抛出double型异常
    case 2: throw 'a'; //抛出char型异常
    case 3: throw Li; //抛出Derive1类的Li异常对象
    case 4: throw Derive2(); //抛出Derive2类的异常对象
    case 5: throw "abcd"; //抛出字符串的异常
    case 6: throw Base(); //抛出Base类的异常对象
   }
   cout<<"switch end.\n";
  }
  catch(int) //捕获int型异常后的异常处理
  { cout<<"catch a int.\n";}
  catch(double& value) //捕获double型异常后的异常处理
  { cout<<"catch a double,this value is "<<value<<"\n";}
  catch(char) //捕获char型异常后的异常处理
  { cout<<"catch a char.\n";}
  catch(Derive1) //捕获Derive1类异常对象后的异常处理
  { cout<<"catch a Derive1 class.\n";}
  catch(Base) //捕获Base类异常对象后的异常处理
  { cout<<"catch a Base class.\n";}
  catch(...) //捕获前面未捕获异常的所有异常处理
  { cout<<"Nothing is caught.\n"; }
 }
}

void main15_3()
{ fun(); }

//【例15.4】当不能处理抛出对象时,可以显示一条自已定义的出错信息"….error!"

#include <eh.h>

typedef void(*PFV)();

void error_message()
{
 cout<<"....error!"<<endl;
} 

void fun3() //设置terminate()要调用的函数error_message()
{
 PFV p=set_terminate(&error_message); 
 try {
     throw 'a'; //抛出char类型的异常对象
 }
 catch(int){ //捕获int类型的异常对象
     cout<<"catch a int.\n";
 }
 catch(double){ //捕获double类型的异常对象
     cout<<"catch a double.\n";
 }
 set_terminate(p); //恢复terminate()要调用的系统函数abort
}

void main15_4()
{ fun(); }

//【例15.5】在Vector类中进行下标越界、数组尺寸超长异常处理。

class Vector5{ 
 int *p;
 int sz;
 enum{ max=3000}; //数组的最大尺寸
public:
 Vector5(int size){ 
  if (size<0||size>max)
  throw Size(); //抛出数组尺寸超长异常对象
  p=new int[size];
  sz=size;
 }
 ~Vector5()
 { delete[]p; }
 int size() const { return sz;}
 class Range{}; //下标越界异常类
 class Size {}; //数组尺寸超长异常类
 int& operator[](int i){
 if (i>=0&&i<sz) return p[i];
     throw Range(); //抛出下标越界异常对象
 }
};

void UseVectors(int size,int range){
 Vector5 vv(size); //定义一个大小为size的数组对象vv
 vv[range]=10; //给数组中指定下标range的元素赋值为10
}

void f(int size,int range){
    try{ 
  UseVectors(size,range);
  cout<<"Unexception in this time.\n"; //没有异常发生
 }
 catch(Vector5::Range) //捕获数组越界的异常处理
 { cout<<"Vector:: out of range!"<<endl; }
 catch(Vector5::Size) //捕获数组尺寸超长的异常处理
 { cout<<"Vector5::Size error!"<<endl;
     size=size>0?--size:0; //将数组尺寸进行正确的调整,进行size--
     cout<<size<<endl;
     f(size,range); //递归进行调整数组尺寸size
 }
 cout<<"Function f() end."<<endl;
}

void main15_5()
{ 
 int size,range;
 cout<<"input size,range:";
 cin>>size>>range;
 f(size,range);
}

//【例15.6】对算术运算中出现的异常用异常枚举法处理

enum MatheErr{Overflow,Underflow,Zerodivide};

void fun6()
{
     //…
     try {
      //…
      throw Zerodivide;
  }
     catch(MatheErr fe)
  {
   switch(fe)
   {
    case Overflow: //…
    case Underflow: //…
    case Zerodivide:break; //…
   }
  }
   //…
}

void main15_6()
{
 fun6();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值