太好了,这就是 C++ 异常处理的三大核心关键词:try、catch、throw。下面我给你讲
🎯 一、三大关键词简介
| 关键词 | 作用 |
|---|---|
throw | 抛出异常(出错时执行) |
try | 标记一段可能抛异常的代码块 |
catch | 捕获并处理异常 |
🧱 二、基本语法格式
try {
// 有可能抛异常的代码
throw 异常对象;
}
catch (类型 参数) {
// 异常处理代码
}
✅ 三、示例代码
#include <iostream>
#include <stdexcept> // 提供标准异常类
int divide(int a, int b) {
if (b == 0)
throw std::runtime_error("除数不能为 0!");
return a / b;
}
int main() {
try {
int result = divide(10, 0);
std::cout << "结果是:" << result << std::endl;
} catch (const std::exception& e) {
std::cerr << "捕获异常:" << e.what() << std::endl;
}
}
输出:
捕获异常:除数不能为 0!
🧠 四、throw 可以抛哪些东西?
throw 42; // int
throw "error message"; // const char*
throw std::runtime_error("msg"); // 推荐:std::exception 类型
建议统一用 std::exception 或自定义异常类,方便 catch。
🔍 五、catch 多重匹配和万能捕获
try {
// ...
} catch (const std::out_of_range& e) {
// 处理越界
} catch (const std::exception& e) {
// 处理其他标准异常
} catch (...) {
// 万能 catch,兜底
}
...表示捕获任何异常(不管是什么类型)- 匹配顺序很重要,从上到下匹配,先写具体,后写通用!
🎓 六、throw 抛出的位置 & 栈展开
- 异常从
throw开始,沿着函数调用栈“层层往外传” - 如果没有
catch,程序会调用std::terminate()强行退出
void f() {
throw std::runtime_error("Boom");
}
void g() {
f(); // 异常会从 f 抛出来
}
int main() {
try { g(); } catch (...) { std::cout << "Caught" << std::endl; }
}
❗ 七、配套机制
| 关键词或函数 | 用途 |
|---|---|
std::exception | 所有标准异常的基类 |
std::terminate() | 没有被捕获的异常会触发它 |
noexcept | 指定函数不会抛异常,抛了就 terminate |
throw; | 在 catch 中重新抛出当前异常 |
🧹 八、异常和资源管理:RAII 大显身手
即使抛异常,局部变量也会正常析构:
class Guard {
public:
~Guard() { std::cout << "资源已释放\n"; }
};
int main() {
try {
Guard g;
throw 1;
} catch (...) {
std::cout << "异常被捕获\n";
}
}
输出:
资源已释放
异常被捕获
✅ 九、总结口诀版:
try 是防火墙,throw 是爆炸点,catch 是灭火器。
如果你想继续深入,我可以:
- 给你讲讲 C++11/17 中异常的优化机制(
noexcept,std::optional替代异常) - 写一个小型异常封装库(适合实际工程)
- 或者讲讲异常在底层是怎么实现的(栈展开、typeinfo、RTTI)
你感兴趣哪个方向?😎
6304

被折叠的 条评论
为什么被折叠?



