003-2 异常(完)

  1. 程序有时会遇到运行阶段错误,导致程序无法正常地运行下去
  2. 异常为禅理这种意外情况提供了一种功能强大而灵活的工具

传统方法

  • abort & exit:
  • abort:
  1. abort函数的原型位于头文件cstdlib
  2. 函数功能:
    (1)向标准错误流cerr发送消息abnormal program termination(程序异常终止)
    (2)终止程序的执行
    (3)abort是否刷新文件缓冲区取决于实现
    (4)返回一个随实现而异的值,告诉操作系统,处理失败
  • exit:
  1. exit直接终止程序的执行,并退出
  2. 刷新文件缓存区,但不显示消息
  3. exit函数需要传递一个整型参数,exit会返回该值
double hmean(double a, double b)
{
	if(a == -b)
	{
		std::abort();  //exit(10);
	}
	return 2.0*a*b/(a+b);
}
  • 返回错误码:
  1. 除异常终止程序外,可以使用函数的返回值来指出问题
  2. 另一种在某个地方存储返回条件的方法是使用一个全局变量

在这里插入图片描述

异常机制

  1. 异常是对程序运行过程中发生异常情况的一种响应
  2. 异常提供了将控制权从程序的一部分传递到另一部分的途径
  • 异常处理的组成:
  1. 引发异常,使用关键字throw
    (1)throw语句是跳转,即命令程序跳到另一条语句
    (2)关键字throw后的值(字符串对象)指出了异常的特征
  2. 使用异常处理程序捕获异常,使用关键字catch
    (1)catch关键字表示捕获异常,处理程序以catch开头
    (2)关键字catch后是位于括号中的类型参数,它指出了异常处理程序要响应的异常类型
    (3)最后是用花括号括起的代码块,指出要采取的措施
    (4)关键字catch和异常类型用作标签,指出当异常被引发时,程序应跳到这个位置执行
    (5)异常处理程序也被称为catch块
  3. 使用try块(特定的异常可能被激活的代码块),使用关键字try
    (1)try块后面跟着一个或多个catch块
    (2)关键字try的后面是一个由花括号括起的代码块,表明需要注意这些代码引发的异常
  1. 执行完try块中的语句后,若未引发任何异常,则程序跳过try块后面的catch块,继续执行catch块后面的第一条语句
  2. 执行throw语句类似于执行返回语句
    (1)throw语句也将终止函数的执行
    (2)throw语句不是将控制权返回给调用程序,而是导致程序沿着函数调用序列后退,直到找到包含try块的函数
  3. 若函数引发了异常,但没有try块或没有匹配的catch块时,默认情况下,程序最终将调用abort函数

在这里插入图片描述

  • c++11支持的异常规范:
  1. 可以使用新增的关键字noexcept指出函数不会发生异常

在这里插入图片描述

  • 未捕获异常:
  1. throw抛出异常,却没有try块或没有匹配的catch块时,则异常被称为未捕获异常
  2. 当出现未捕获异常时,默认情况下,会导致程序异常终止
  3. 修改程序对未捕获异常的反应:
    (1)未捕获异常不会导致程序立即异常终止
    (2)程序会首先调用terminate(),默认情况下,terminate()会调用abort函数
    (3)可以通过调用set_terminate()来修改terminate()函数的行为
    (4)set_terminate()函数和terminate()函数都是在头文件exception中声明的

在这里插入图片描述
在这里插入图片描述

对象用作异常类型

  1. 引发异常的函数传递一个对象,可以使用不同的异常类型来区分不同的函数不同的情况下引发的异常,即确定异常的位置与类型
  2. 对象可以携带信息,程序员可以根据这些信息来确定引发异常的原因,即确定发生异常的原因
  3. 使用省略号来表示异常类型,从而捕获任何类,并且将捕获所有异常的catch块放在最后面

在这里插入图片描述

  1. 引发异常时,编译器总是创建一个临时拷贝,即使catch块中指定的是引用
  2. 基类引用可以执行派生类对象:假设有一组通过继承关联起来异常类型,则在异常规范中只需列出一个基类引用,它将与任何派生类对象匹配
  3. 如果一个异常类继承层次结构,应这样排列catch块:将捕获位于层次结构最下面的异常类的catch语句放在最前面,将捕获基类异常的catch语句放在最后面

在这里插入图片描述
在这里插入图片描述

栈解退

  1. 栈解退:
    (1)函数由于出现异常(而不是由于返回)而终止,程序也将释放栈中的内存
    (2)但不会再释放栈的第一个返回地址后停止,而是继续释放栈,直到找到一个位于try块中的返回地址
    (3)随后,控制权将转换到块尾的异常处理程序(catch块),而不是函数调用后面的第一条语句
  2. 函数返回相同,将会释放栈中的自动变量,若该自动变量为类对象,类的析构函数将被调用
    (1)函数返回仅仅处理函数放在栈中的对象
    (2)throw语句则处理try块throw语句之间整个函数调用序列放在栈中的对象
    (3)若没有栈解退这种特性,则引发异常后,对于中间函数调用放在栈中的自动类对象,其析构函数将不会被调用

在这里插入图片描述

exception类

  1. exception头文件定义了exception类,C++可以把它用作其他异常类的基类
  2. 代码可以引发exception异常,也可以将exception类用作基类
  3. exception类中有一个名为what的虚拟成员函数,它返回一个字符串,可以在从exception派生而来的类中重新定义它

在这里插入图片描述

  • stdexcept异常类:
  1. stdexcept是头文件,它定义了多个以公有方式exception派生而来的类,如logic_error类和runtime_error
  2. 这些类的构造函数接受一个string对象作为参数,该参数提供了方法what()C-风格字串方式返回的字符数据

在这里插入图片描述

  • logic_error的派生类:
  1. 异常类系列logic_error描述了典型的逻辑错误
  2. domain_error: 函数在参数不再定义域时引发4.
  3. domain_error: 给函数传递了一个意料之外的值
  4. length_error: 指出没有足够空间来执行所需的操作
  5. out_of_bounds: 指示索引错误
  • runtime_error的派生类:
  1. runtime_error描述了可能在运行期间发生但难以预计和防范的错误
  2. range_error: 计算结果可能不再函数允许的范围之内
  3. overflow_error: 上溢错误
  4. underflow_error: 上溢错误
  • bad_alloc异常和new:
  1. C++的最新处理方式是让new引发bad_alloc异常
  2. bad_alloc类是从exception类公有派生而来的
  3. C++标准提供了一种在失败时返回空指针new

在这里插入图片描述
在这里插入图片描述

异常、类和继承

  1. 可以从一个异常类派生出另一个
  2. 可以在类定义中嵌套异常类声明来组合异常
  3. 这种嵌套声明本身可以被继承,还可以作为基类

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_46427273

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值