c++++的异常处理机制通过try、catch和throw实现,其核心在于捕获并处理运行时错误以避免程序崩溃。try块包裹可能出错的代码,若发生异常则用throw抛出异常对象,随后由匹配的catch块捕获并处理,支持多类型捕获及兜底捕获(catch ...),同时推荐使用标准库或自定义异常类以增强信息携带能力。此外,异常应仅用于非正常可预见错误而非流程控制,需注意栈展开过程中的资源释放问题,结合raii技术确保异常安全,并权衡性能开销。

C++的异常处理机制是通过 try、catch 和 throw 三个关键字配合使用的。它的核心思想是在程序运行过程中,当发生错误或异常情况时,能够跳过正常的执行流程,转而进入专门的错误处理逻辑,而不是让程序崩溃或者继续执行错误的路径。

try 是用来“尝试执行”的代码块
在 C++ 中,你把可能出错的代码放在 try 块里。如果在 try 块中发生了异常(比如除以零、数组越界等),你可以使用 throw 抛出一个异常对象。

例如:
立即学习“C++免费学习笔记(深入)”;
try {
// 可能会抛出异常的代码
if (someErrorCondition) {
throw "发生错误了!"; // 抛出一个字符串类型的异常
}
}这里的重点是:只有被 try 包裹的代码才能被 catch 捕获到异常。如果你不写 try,那异常就不会被捕获,程序就会终止。

catch 是用来“捕获并处理”异常的部分
紧跟在 try 后面的是一个或多个 catch 块,它们负责接收和处理从 try 中抛出的异常。你可以根据抛出的对象类型来匹配对应的 catch 块。
比如:
try {
throw 123; // 抛出一个整数
}
catch (int e) {
cout << "捕获到了整型异常:" << e << endl;
}
catch (...) {
cout << "未知类型的异常" << endl;
}几个要点:
- 你可以有多个
catch块来处理不同类型的异常。 -
catch (...)表示捕获所有类型的异常,通常作为兜底使用。 - 异常类型要尽量具体,这样更容易定位问题。
throw 是触发异常的关键字
当你发现某个错误无法继续正常执行下去时,就可以使用 throw 主动抛出一个异常。它后面可以跟任意类型的表达式,比如 int、string,甚至是自定义的异常类。
比如:
if (denominator == 0) {
throw std::runtime_error("除数不能为零");
}建议:
- 不要用裸指针或基本类型抛异常,推荐用标准库中的异常类(如
std::exception的派生类)。 - 自定义异常类可以携带更多信息,方便调试。
异常处理的常见误区与注意事项
不要滥用异常
异常是用来处理“非正常但可预见”的错误的,不是用来控制程序流程的。比如,输入验证失败就不要用异常,直接返回错误码更合适。注意栈展开的过程
当异常抛出后,程序会自动退出当前函数调用栈,直到找到匹配的catch块。这个过程叫做“栈展开”。在这个过程中,局部变量会被析构(RAII原则很重要)。异常安全问题
如果你在抛出异常前分配了资源(比如内存、文件句柄),一定要确保这些资源能正确释放。使用智能指针、锁等 RAII 技术是关键。性能开销
虽然现代编译器优化得很好,但在频繁出错的场景下,使用异常可能会带来一定的性能损耗。所以只在真正需要的地方使用。
基本上就这些。C++ 的异常机制不算太复杂,但细节很多,尤其在大型项目中,合理设计异常处理结构对稳定性和可维护性都很重要。









