【C++学习笔记】异常处理

在学python的时候,我们知道python中可以利用try。。。。except语句来检查代码中的错误,那么在C++中,有没有类似的体系去帮助程序员发现程序中的异常情况呢,答案是肯定的,现在,我们来介绍一下C++中的异常处理机制。

组成

C++中异常处理机制包括三部分——检查(try)、抛出(throw)和捕捉(catch)。其工作形式是:把需要检查的语句放在try语句块中,如果在语句块中发现错误,就利用throw把异常的信息提取出来,然后在try语句块外catch语句捕捉异常信息,并执行catch后面的语句,程序回到main主函数。

这样说比较抽象,我们可以这么理解。假设我们的程序是一个鱼群,里面本来只有鲫鱼(正常的程序),可是有一天,里面突然多出了好多其他的鱼(比如黄鱼、龙利鱼、草鱼。。。),这个时候系统要怎么把异常找出来呢?

系统的做法是——先把一部分鱼围在一个圈里(定义try语句块),然后派一个人下去找混在其中的鱼(利用条件语句说明异常条件),然后找到鱼后把鱼丢出来(利用throw语句抛出异常信息),在群外有一些人拿着不同的鱼篓(catch)接收这些抛出来的鱼(异常信息),每种鱼篓只能接收某种特定的鱼,当鱼篓接收到不同鱼的时候,进行不同的处理,假如没有鱼丢出来,说明里面没有其他的鱼,程序跳过catch语句块执行下一行语句。

使用

try{
要检查的程序块
。。。。。。
}
catch(X){

假如接收到对应的异常信息后的处理
。。。。。。
}
X可以为以下几种类型:

  • 数据类型 ,表示catch接收某一类型的异常变量 例如:catch(double){}
  • 数据类型+参数名,catch接收到该类型数据,并且留有一份该数据的拷贝,方便在后面的操作中使用。 例如:
    catch(double x){cout<<x<<endl;} 此时异常信息的值就复制到了x中。
  • … 表示可以接收任何类型的异常信息。例如 catch(...){}

注意事项:

  1. 被检测函数必须放在try中,否则不起作用。
  2. try和catch必须以一个整体出现,catch块是try-catch中的一部分,不能单独出现,并且必须要和try紧密相连,中间不能有任何其他语句。但是try后面不一定要有catch,表示只做检查不做处理。(try和catch的关系和if-else的关系是类似的。)
  3. try和catch块中必须有花括号括起来的复合语句,哪怕花括号中只有一个语句。(这点与if else 不同)
  4. 一个try-catch块中只能有一个try块,但却可以有多个catch块,以便不同异常信息匹配。

throw机制的深度解释

实际上在上例中用鱼的例子是有点不准确的。throw是将后面的对象复制构造成一个新的对象,称为异常对象。

然后把这个异常对象放在系统的一个独立的分区中,而这个分区是不分范围的,

也就是说,找出来的异常对象放在这个独立分区后,不管是哪一级的catch,只要找到了符合catch接收条件的异常变量,都可以把它“认领走”。而这个分区中一旦有异常变量,程序会执行catch后面的代码,如果catch运行成功,则该异常变量就会被释放,然后转到到上一级程序,如果catch类型不匹配,则直接转到上一级程序。假如到了主函数main中异常变量依然存在那么程序就会直接停止。

总结来说就是:throw会抛出异常变量,而只要有异常变量就会让程序无法往下运行,catch会“认领走”异常变量,使得程序能够继续运行。

我们举个例子:

#include<iostream>
using namespace std;
int main()
{
void f1();
try
{f1();}
catch(double)
{
cout<<"OK0!"<<endl;
}
cout<<"end0"<<endl;
return 0;
}

f1{
void f2();
try{
f2();
}
catch(int){
cout<<"OK1!"<<endl;
}
cout<<"end1"<<endl;
}
void f2(){
void f3()
try{
f3();
}
catch(char){
cout<<"OK2"<<endl;
}
cout<<"end2"<<endl;
}
void f3(){
double a=1;
try{
throw a;
}
catch(char){
cout<<"OK3"<<endl;
}
cout<<"end3"<<endl;
}

这个例子我们做了一个多重嵌套,看起来很复杂,但是假如我们掌握了上面的原理,解答起来是很轻松的。

总的解题思路是:

核心思路两点
看看异常区里有没有异常变量,如果有,运行catch,运行完后,就停止下面的代码,转到上一层函数,直到有catch愿意接收这个异常变量为止。
假如有catch接收掉了那么之后运行时异常区就没有异常变量,程序就可以继续运行了。

函数声明中进行异常情况指定

函数声明时可以对其中可能出现的异常情况进行指定,以方便阅读。
下面分为四种情况说明:

第一种:

int function(double, double, double)throw(double)

说明了在执行这个函数后,只能抛出(严谨一点是:在异常区中国添加)double类的异常信息。其他类型的都是无效的。

第二种

int function(double, float, int)throw(double,float,int)

说明了在执行这个函数后,能抛出double、float、int 类型异常信息。

第三种

  int function(double, float, int)throw(double,float,int);

不加throw说明有可能抛出任何类型的异常数据。

第四种

int function(double, float, int)throw(double,float,int)throw;

说明不能抛出异常数据。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值