前言
在 C 语言中,我们通过错误码处理异常,但错误码只能返回简单状态,无法携带详细错误信息,且需要手动逐层检查,繁琐且易遗漏。C++ 的异常机制则彻底改变了这一现状 —— 它将'错误检测'与'错误处理'分离,允许程序在出错时抛出异常对象(携带完整错误信息),在合适的位置捕获并处理,让代码更优雅、逻辑更清晰。本文结合核心知识点和代码,从异常的基本语法、栈展开机制、捕获匹配规则,到异常安全、标准库异常体系,再到实战案例,全方位拆解 C++ 异常,帮你从'会用'到'用好',应对大型项目的错误处理需求。
一。异常的核心概念与基本语法
- 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理,异常使得我们能够将问题的检测与解决问题的过程分开,程序的一部分负责检测问题的出现,然后解决问题的任务传递给程序的另一部分,检测环节无需知道问题的处理模块的所有细节
- C 语言主要通过错误码的形式处理错误,错误码的本质就是对错误信息进行分类编号,拿到错误码以后还要去查询错误信息,比较麻烦。而异常是抛出一个对象,这个对象可以函数更全面的拿到各种信息。
1.1 异常的核心思想
- 抛出(throw):程序遇到错误时,通过
throw抛出一个异常对象(可以是任意类型,推荐自定义异常类); - 捕获(catch):通过
catch语句捕获指定类型的异常,执行对应的处理逻辑; - try 块:
try包裹可能抛出异常的代码,后续紧跟一个或多个catch块,用于匹配异常
分析:
- 程序出现问题时,我们通过抛出 (throw) 一个对象来引发一个异常,该对象的类型以及当前调用链决定了应该由哪个 catch 的处理代码来处理该异常。
- 被选中的处理代码是调用链中与该对象类型匹配且抛出异常位置最近的那一个。根据抛出对象的类型和内容,程序的抛出异常部分告知异常处理部分到底发生了什么错误。
- 当 throw 执行时,throw 后面的语句将不再被执行。程序的执行从 throw 位置跳到与之匹配的 catch 模块,catch 可能是同一函数中的一个局部的 catch,也可能是调用链中另一个函数的 catch,控制权从 throw 位置转移到了 catch 位置。这里还有两个重要的含义:1. 沿着调用链的函数可能提早结束退出。2. 一旦程序开始执行异常处理,沿着调用链创建的对象都将销毁。
- 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个局部对象,所以会生成一个拷贝对象,这个拷贝的对象会在 catch 子句后销毁。(这里的处理类似于函数的传值返回)
1.2 基础语法格式和最简示例
基本语法格式:
/*-----------------------------------------------------------------
try {
// 可能抛出异常的代码
可能出错的函数 ();
} catch (异常类型 1& e) {
// 处理类型 1 异常
} catch (异常类型 2& e) {
// 处理类型 2 异常
} catch (...) {
// 捕获任意类型异常(兜底处理)
}
/*-----------------------------------------------------------------
最简示例(除零异常):
#include <iostream>
#include <exception>
#include <string>
using namespace std;
{
(b == ) {
();
} {
(()a / ()b);
}
}
{
{
len, time;
cin >> len >> time;
cout << (len, time) << endl;
} ( exception& e) {
cout << e.() << endl;
}
cout << << __LINE__ << endl;
}
{
() {
{
();
} ( string& s) {
cout << s << endl;
} ( exception& e) {
cout << e.() << endl;
} (...) {
cout << << endl;
}
cout << << __LINE__ << endl;
}
;
}








