C++ 异常
0. 前言
在 C++ 学习的过程中,异常(Exception) 是一个既重要又常常被忽视的知识点。很多初学者更习惯使用 错误码 或者 断言 来处理问题,却很少系统地去理解和使用异常机制。事实上,异常的设计初衷,就是为了解决 C 语言时代'错误处理困难、代码可读性差'的痛点。
在现代软件开发中,系统往往具有更高的复杂性,函数调用链很长,模块之间紧密协作。如果依赖传统的错误返回值,就需要'层层上传',一旦遗漏检查就可能导致严重的 bug;而直接使用 assert 终止程序,也会让用户难以接受。C++ 提供的 异常机制 恰好为我们提供了一个优雅的解决方案:
- 错误信息能够在调用链上自动传递;
- 外层可以通过
catch块集中处理错误; - 结合
RAII思想,还能有效避免资源泄漏问题。
本文将带你系统学习 C++ 异常:从传统 C 风格错误处理的不足说起,再到异常的语法规则、抛出与捕获的过程、异常安全与 RAII、统一异常体系的设计,以及标准库提供的异常层次。
1. 传统 C 风格的错误处理:为何需要异常?
C 语言中错误处理常见两种做法:
- 终止程序(如
assert为false时直接终止程序):缺陷:并不能明确知道是什么错误,用户难以接收错误信息- 内存错误(数组越界,未初始化/空指针/无效地址的访问,野指针,内存泄露,同一块空间释放多次等等)
- 除 0 错误,会直接终止程序
- 返回错误码(需配合
errno),缺陷:需要调用者层层检查和传递对应的错误,既繁琐又易出错- 如系统的很多库的接口函数都是通过把错误码放到 errno 中,表示错误
- 实际工程里,多数选择返回错误码,极少数'致命错误'直接终止。
- 实际工程中,C 语言基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的错误
小结: 当函数调用链很深时,错误码方案要求'层层返回',既污染业务逻辑,又容易遗漏。
- 异常机制正是为解决此类痛点而生,异常不会终止程序,并且会将错误信息详细介绍。
不使用异常,传统 C 语言直接终止程序会导致程序崩溃。 使用异常捕获除 0 错误,可以显示出异常的信息并继续运行。
2. C++ 异常的概念
异常是面向对象语言处理错误的一种方式,当一个函数发现自己无法处理的错误时,可以抛出异常,让函数的直接或间接的调用者处理这个错误。异常的抛出和捕获由以下三个关键字配合完成:
- throw:当问题出现时,程序会抛出一个异常 (本质是抛出一个对象)。抛异常使用
throw关键字完成 - try:
try块中包含可能出现异常的代码或者函数,try块中的代码被称为保护代码,放置可能抛出异常的代码,
- catch(异常的类型):跟在
try块之后,用于捕捉异常。catch关键字用于捕获异常,可以设置多个 捕获 抛出的不同类型的。


