C++ 异常机制
异常的基本概念
异常处理机制允许程序中独立开发的部分能够在运行时出现的问题进行通信并做出相应的处理。
C 语言主要通过错误码的形式处理错误,错误码本质就是对错误信息进行分类编号,拿到错误码以后还要去查询错误信息,比较麻烦。C++ 则是异常时抛出一个对象,这个对象可以包含更全面的各种信息。
异常的抛出与捕获
基本语法: 程序出现问题时,我们通过抛出 (throw) 一个对象来引发一个异常,该对象的类型以及当前的调用链决定了应该由哪个 catch 的处理代码来处理该异常。
#include <iostream>
#include <string>
using namespace std;
int main() {
int m = 1;
int n = 0;
try {
if (n == 0) throw string("Divide by zero condition!");
} catch (const string& s) {
cout << s;
}
return 0;
}
try 和 catch 是处理异常信息的配合。try 包含了可能含有异常错误的代码 (如 0 不能做除数),如果有错误那么就会 throw 抛出一个变量让 catch 接受,如果没有抛出那么会跳过 catch。这里我们选择抛出一个常量字符串作为错误信息,让 catch 接受,catch 需要设定能够抓取的错误信息,就像函数参数一样。上面的 catch 的参数就是 const string&,即抓取 string 类型的变量,跟我们抛出的 s 相同。
值得注意的是,可以有多个 catch,因为异常的信息多种多样,我们会自定义多种信息,也就需要多种 catch 来抓取。
throw 执行后,它后面的代码不会执行,而是跳转到匹配的 catch。
蕴含两个含义:
- 沿着调用的函数可能提早退出。
- 一旦程序开始执行异常处理程序,沿着调用链创建的对象都将销毁。
注意:
- 对象拷贝: 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个局部对象,所以会生成一个拷贝对象,这个拷贝的对象会在 catch 子句后销毁。(这里的处理类似于函数的传值返回)
- 栈展开: 抛出异常时会沿着栈寻找最近的匹配要求的 catch,进行跳转
栈展开
抛出异常后,程序暂停当前函数的执行,开始寻找与之匹配的 catch 子句。
首先检查 throw 内部是否有 try,如果有且有符合的 catch,则跳转到 catch;如果无,或者 catch 的类型不匹配,则退出当前函数,在外层调用的函数找,此过程为栈展开。



