玩命加载中 . . .

5.6-try语句块和异常处理


异常(exception)是指程序运行时的反常行为,这些行为超出了函数正常功能的范围。当程序的某一部分检测到一个它无法处理的问题时,需要使用异常处理

异常处理机制包括throw表达式、try语句块和异常类

  • 异常检测部分使用throw表达式表示它遇到了无法处理的问题(throw引发了异常)
  • 异常处理部分使用try语句块处理异常。try语句块以关键字try开始,并以一个或多个catch子句结束。try语句块中代码抛出的异常通常会被某个catch子句处理,catch子句也被称作异常处理代码
  • 异常类用于在throw表达式和相关的catch子句之间传递异常的具体信息

5.6.1 throw表达式

throw表达式包含关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型

Sales_item item1, item2;
cin >> item1 >> item2;
if (item1.isbn() == item2.isbn()) {
    cout << item1 + item2 << endl;
    return 0;   // 表示成功
} else {
    cerr << "Data must refer to same ISBN" << endl;
    return -1;  // 表示失败
}

改成抛出异常的形式

if (item1.isbn() != item2.isbn())
    throw runtime_error("Data must refer to same ISBN");
cout << item1 + item2 << endl;

如果ISBN不一样就抛出一个异常,该异常是类型runtime_error的对象。抛出异常将终止当前的函数,并把控制权转移给能处理该异常的代码

必须初始化runtime_error的对象,方式是给它提供一个string对象或者一个C风格的字符串,这个字符串中有一些关于异常的辅助信息

5.6.2 try语句块

try语句块的通用形式:

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

try语句块中的program-statements组成程序的正常逻辑,其内部声明的变量在块外无法访问,即使在catch子句中也不行

catch子句包含关键字catch、括号内一个对象的声明(异常声明)和一个块。当选中了某个catch子句处理异常后,执行与之对应的块。catch一旦完成,程序会跳过剩余的所有catch子句,继续执行后面的语句

如果最终没能找到与异常相匹配的catch子句,程序会执行名为terminate的标准库函数。该函数的行为与系统有关,一般情况下,执行该函数将导致程序非正常退出。类似的,如果一段程序没有try语句块且发生了异常,系统也会调用terminate函数并终止当前程序的执行

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

程序本来要执行的任务放在try语句块中,因为这段代码可能会抛出一个runtime_error类型的异常

try语句块对应一个catch子句,该子句负责处理类型为runtime_error的异常

5.6.3 标准异常

异常类分别定义在4个头文件中:

  • 头文件exception定义了最通用的异常类exception。它只报告异常的发生,不提供任何额外信息
  • 头文件stdexcept定义了几种常用的异常类
  • 头文件new定义了bad_alloc异常类
  • 头文件type_info定义了bad_cast异常类
异常类 含义
exception 最常见的问题
runtime_error 只有在运行时才能检测出的问题
range_error 运行时错误:生成的结果超出了有意义的值域范围
overflow_error 运行时错误:计算上溢
underflow_error 运行时错误:计算下溢
logic_error 程序逻辑错误
domain_error 逻辑错误:参数对应的结果值不存在
invalid_argument 逻辑错误:无效参数
length_error 逻辑错误:试图创建一个超出该类型最大长度的对象
out_of_range 逻辑错误:使用一个超出有效范围的值

只能以默认初始化的方式初始化exceptionbad_allocbad_cast对象,不允许为这些对象提供初始值。其他异常类的对象在初始化时必须提供一个string或一个C风格字符串,通常表示异常信息。what成员函数可以返回该字符串的string副本


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录