C++ primer 查漏补缺八:try catch

异常类型
在这里插入图片描述

exception

#include <iostream>
#include <string>
#include <exception>
using namespace std;

int main(){
    string str = "http://c.biancheng.net";
  
    try{
        char ch1 = str[100];
        cout<<ch1<<endl;
    }catch(exception e){
        cout<<"[1]out of bound!"<<endl;
    }

    try{
        char ch2 = str.at(100);
        cout<<ch2<<endl;
    }catch(exception &e){  //exception类位于<exception>头文件中
        cout<<"[2]out of bound!"<<endl;
    }

    return 0;
}

运行结果:
[2]out of bound!

可以看出,第一个 try 没有捕获到异常,输出了一个没有意义的字符(垃圾值)。因为[ ]不会检查下标越界,不会抛出异常,所以即使有错误,try 也检测不到。换句话说,发生异常时必须将异常明确地抛出,try 才能检测到;如果不抛出来,即使有异常 try 也检测不到。所谓抛出异常,就是明确地告诉程序发生了什么错误。

第二个 try 检测到了异常,并交给 catch 处理,执行 catch 中的语句。需要说明的是,异常一旦抛出,会立刻被 try 检测到,并且不会再执行异常点(异常发生位置)后面的语句。本例中抛出异常的位置是第 17 行的 at() 函数,它后面的 cout 语句就不会再被执行,所以看不到它的输出。

说得直接一点,检测到异常后程序的执行流会发生跳转,从异常点跳转到 catch 所在的位置,位于异常点之后的、并且在当前 try 块内的语句就都不会再执行了;即使 catch 语句成功地处理了错误,程序的执行流也不会再回退到异常点,所以这些语句永远都没有执行的机会了。本例中,第 18 行代码就是被跳过的代码。

执行完 catch 块所包含的代码后,程序会继续执行 catch 块后面的代码,就恢复了正常的执行流。

为了演示「不明确地抛出异常就检测不到异常」,大家不妨将第 10 行代码改为char ch1 = str[100000000];,访问第 100 个字符可能不会发生异常,但是访问第 1 亿个字符肯定会发生异常了,这个异常就是内存访问错误。运行更改后的程序,会发现第 10 行代码产生了异常,导致程序崩溃了,这说明 try-catch 并没有捕获到这个异常。

throw

     #include<iostream.h>                                 //包含头文件
     #include<stdlib.h>
     double fuc(double x, double y)                        //定义函数
     {
         if(y==0)
         {
            throw y;                                    //除数为0,抛出异常
         }
         return x/y;                                    //否则返回两个数的商
     }
     void main()
     {
         double res;
         try                                            //定义异常
         {
             res=fuc(2,3);
             cout<<"The result of x/y is : "<<res<<endl;
             res=fuc(4,0);                                //出现异常
         }
         catch(double)                                    //捕获并处理异常
         {
             cerr<<"error of dividing zero.\n";
             exit(1);                                    //异常退出程序
         }
     }

std::bad_alloc 异常

内存耗尽的异常。如果new不能分配所要求的内存空间,就会抛出类型为bad_alloc的异常。如下所示:


int *a;
 
try
{
    //分配内存
    a= new int[bigBigNum];
}
catch(std::bad_alloc)
{
    //异常处理
    //弹出提示对话框
    // 返回

我们也可以改变new的方式来组织它抛出异常:

int *p0 = new int;//如果分配失败,new抛出异常
int *p= new(nothrow) int;//如果分配失败,new返回空指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值