C++异常处理

异常

程序在运行过程中出现的错误称为异常。

异常处理

对异常的处理称为异常处理。 处理程序中的错误非常困难,如服务器上长期运行的服务程序有80%的代码用于错误检测和错误处理。

传统的异常处理

基本是采取判断或分支语句来实现
例一:

    #include<iostream>
    using namespace std;
    int main(void){
        int m,n;
        cin>>m>>n;//m/n;
        if(n==0)
           cout<<"除数为零,错误";
        else
           cout<<m/n; 
    }
优点:

可以满足小型应用程序的需要

缺点:

在一个大型软件系统中,包含许多模块,每个模块又包含许多函数,函数之间又相互调用,比较复杂。如果在每一个函数中都设置处理异常的程序段,会使程序过于复杂和庞大。传统的异常处理机制无法保证程序的可靠运行,而且采用判断或分支语句处理异常的方法不适合大量异常的处理,更不能处理不可预知的异常。

C++提供的异常处理

C++提供的异常处理机制逻辑结构非常清晰,而且在一定程度上可以保证程序的鲁棒性(或健壮性,robustness)

抛出异常(throw)、检查异常(try块)、和捕获(catch块)

基本思想:把需要检测的程序放到try块中,把处理异常的程序放到catch中。如果在执行一个函数时发现异常,不在函数内立即处理异常,而是抛出异常信息,传递给他的上一级函数(主调函数),它的上一级函数捕获这个异常后再近些处理。如果上一级函数也不处理,就逐层向上传递。如果遇到最高一级(如main函数),就只能终止程序的执行

优点:

这样的异常处理方法使得异常的引发和处理机制分离,而不是由同一个函数完成。这样做法的好处是使底层函数(被调用函数)着重于解决实际任务,而不必过多地考虑对异常的处理,以减轻底层函数的负担,把异常处理的任务上移到上层去处理。

1、try 语句

try语句的作用是启动异常处理机制。

格式:

try
{
<语句序列>
}
例二:

 try{  
 f(filename); 
 }
2、throw 语句

throw语句用于在发现异常情况时抛掷(产生)异常对象。

格式:

throw <表达式>;
例三:


 void f(char * filename){
       ifstream file(filename);
       if(file.fail)
           throw filename;//产生异常对象
  }
3、catch 语句

catch语句用于捕获throw 抛掷的异常对象并处理相应的异常。

格式:

catch(<类型><变量>)
{
<语句序列>
}
例四:

  #include<iostream>
  using namespace std;
  void fun(int x){
    try{
         if(x==0)
              throw 1;
         if(x==1)
              throw 'a';
         if(x==2)
              throw 1.0;
         throw "";
    }
    catch(int){
         cout<<"x=0";
    }
    catch(char){
         cout<<"x=1";
    }
    catch(double){
         cout<<"x=2";
    }
    catch(const char *){
         cout<<"x="<<x;
    }
  } 
  int main(void){
        int x;
        cin>>x;
        fun(x);
  }
异常处理的详细方法:
  1. 首先将需要检查的、也是容易引起异常的语句或程序段放在try块的{}内
  2. 如果在执行try块的复合语句过程中没有发生异常,则跳过catch语句,继续执行
  3. 如果执行try内的复合语句或被调用函数发生异常,则throw语句抛出一个异常信息,转到它的上一级函数
  4. Throw抛出的异常信息传到try_catch结构,系统寻找与之匹配的catch子句。
  5. 执行异常处理语句后,程序继续执行catch子句后面的语句。

注意:

  • 被检测的语句必须放在try块中,否则不起作用 try和catch作为一个整体出现,不能单独使用,且二者之间也不能插入其他语句
  • try和catch中必须使用有花括号括起来的复合语句,即使花括号内只有一个语句也不能省略花括号
  • 一个try_catch结构中只能有一个try块,但却可以有多个catch块,以便与不同的信息匹配。catch后面的括号中,一般只写异常信息的类型名,catch只检查所捕获的异常信息的类型,不检查他们的值。
  • 如果在子句catch中没有指定异常信息的类型,而用了删节号“…”,则表示它可以捕获任何类型的异常信息。
    例五:
       #include<iostream>
       using namespace std;
       void fun(int x){
        try{
           if(x==0)
              throw 1;
           if(x==1)
              throw 'a';
           if(x==2)
              throw 1.0;
           throw "";
        }
        catch(int){
           cout<<"x=1"; 
        }
        catch(...){ 
           cout<<"..."<<x;
        }
       } 
       int main(void){
            int x;
            cin>>x;
            fun(x);
       }`
  • try - catch结构可以和throw出现在同一函数中,也可以不在函数中。在某种情况下,throw语句被多次调用。此时,它将把当前正在处理的异常信息再次抛出,给其上一层catch块处理。(try的嵌套使用)
    例六:
    #include<iostream>
    using namespace std;
    void fun(int x){
     try{
      if(x==1)
          throw 1;
      if(x==2)
          throw 'a';
      throw " ";
     }
     catch(int){
          cout<<"x=1"; 
      throw 1;
     }
     catch(char){ 
         cout<<"x=2";
      throw 'a';
     }
     catch(const char *){
         cout<<"x="<<x;
      throw " ";
     }
    } 
    int main(void){
     int x;
     cin>>x;
     try{
        fun(x);
     }
     catch(int){
        cout<<" int";
     }
     catch(char){
        cout<<" char";
     }
     catch(const char *){
        cout<<" const char *";
     }
    }
  • 在C++中,一旦抛出一个异常,而程序又不捕获的话,那么系统就会调用一个系统函数terminate,由它调用abort终止程序。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值