C++ Primer 5.6 try语句块与异常处理

异常处理也是我经常学了就忘的东西,因为学生时代的课程设计往往情况单一,往往用不到异常处理,再加上我本人经常懒得去考虑异常检测处理的情况,这一部分的知识一直学了就忘,今天利用这个机会好好记录,重新学习一下。

异常顾名思义,是程序在运行过程中遇到的无法处理的问题,超出了程序解决的能力。典型的异常有两点:一是失去数据库连接,其二就是遭遇意外输入。当程序遇到异常的过程中,检测到异常的部分应该能发出某种信号表明其遇到了异常情况,它不需要确定异常发生的代码处,只需表明当下确实有异常的出现即可。如果程序中含有可能发生异常的代码,那么也应当有专门处理异常的方法,例如遇到异常输入时让用户重新进行输入,遭遇数据库连接丢失时发出警告。

C++异常处理机制由异常检测和异常处理两部分组成。其中异常处理包括:

throw表达式,异常检测部分使用throw表达式来抛出它所遇到的无法解决的问题。

try语句块,异常处理部分使用try语句块处理异常,在try中代码抛出的异常通常会被某个对应的catch子语句捕捉处理。、

同时还有一套异常类用于传递异常的具体信息。

1. throw表达式

throw表达式运用非常简单,在特定位置处抛出一个异常。范例代码如下:

//将两本相同isbn的书籍进行相加
//当输入的两本书isbn不相同时抛出异常
if(book1.isbn() != book2.isbn()){
    throw runtime_error("Data must refer to same isbn");
}

若ISBN值不一样时就会抛出异常,该异常的类型是runtime_error,抛出这个异常会终止当前函数运行,并将控制权转移给可以处理该异常的代码块。

runtime_error异常是标准库异常的一种,定义在stdexcept头文件中。

2. trycatch语句块

trycatch的通用语法形式为:

try{
    program-statements
}catch(exception-declaration){
    handler-statements
}catch(exception-declaration){
    handler-statements
}...

其中catch子句包括三部分,catch关键字,括号内的(可能未命名)对象声明(异常声明),以及一个块。需要注意的是,在try中声明的对象即便是catch中也无法使用。

针对上述的相加功能,我们可以利用trycatch来抛出处理异常。

while(cin >> item1 >> item2){
    try{
        //执行相加代码
        //如果失败则抛出异常
    }catch(runtime_error err){
        cout << err.what()
             << "\nTry again? y or n?" << endl;
        char c;
        cin >> c;
        if(!cin || c == 'n') break;
    }
}

处理异常时我们输出了一个异常信息err.what(),实际上每个标准库异常类都定义了名为what()的成员函数,它没有输入参数,返回值为C风格字符串。

还需要注意的是对抛出的异常如何寻找对应的catch语句进行处理:当异常被抛出时,首先找到抛出异常的函数,寻找是否有匹配的catch,如果没有则立即终止该函数,并在调用该函数的函数中进行寻找,以此类推,直到找到匹配的catch为止。

如果最终仍未找到对应catch语句,程序会转到名为terminate的标准库函数,该函数行为与系统有关,一般来说调用该函数会使得程序非正常停止。

3. 标准异常

C++定义了一组类用于报告标准库函数遇到的问题,分别定义在4个头文件中

  1. exception头文件定义了最通用的异常类exception,只报告异常的发生而不提供任何额外信息
  2. stdexcept头文件定义了几种常用的异常类
  3. new头文件定义了bad_alloc异常类型
  4. type_info头文件定义了bad_cast异常类型

其中stdexcept定义的异常类是我们平时最有可能遇到的,例如:

exception最常见的问题
runtime_error运行时才能发现的问题
range_error运行时错误,生成结果超出了有意义的值域
overflow_error运行时错误,计算上溢
underflow_error运行时错误,计算下溢
logic_error程序逻辑错误
domain_error参数对应值不存在
invalid_error无效参数
length_error试图创建一个超出最大长度的对象
out_of_range使用一个超出有效范围的值

 另外需要注意的是,当我们使用exception、bad_alloc、bad_cast对象时不允许为他们赋初始值。而其他异常类型则相反,应该使用string对象或c风格字符串进行初始化而不允许默认初始化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值