汇知百科
白蓝主题五 · 清爽阅读
首页  > 系统软件

C++异常捕获:让程序更稳地应对突发状况

异常不是问题,没处理才是

写代码时,谁都希望一切顺利。但现实往往不那么理想——文件打不开、内存分配失败、网络断了,这些意外随时可能发生。C++ 提供了异常机制,让我们能优雅地应对这些“万一”。

异常捕获的核心是 try-catch 结构。把可能出问题的代码放进 try 块里,一旦抛出异常,程序会立刻跳转到匹配的 catch 块进行处理,而不是直接崩溃。

基本语法长这样

try {
int* arr = new int[1000000000]; // 可能因内存不足抛出异常
} catch (const std::bad_alloc& e) {
std::cout << "内存不够了:" << e.what() << std::endl;
}

上面的例子中,new 操作失败会抛出 std::bad_alloc 类型的异常,catch 捕获后输出提示信息。程序继续运行,不会突然退出。

捕获不同类型的异常

异常可以是各种类型:内置类型(如 int)、标准库异常(继承自 std::exception),甚至是自定义类。catch 可以根据类型分别处理:

try {
if (file_not_found) {
throw std::runtime_error("文件不存在");
}
if (invalid_input) {
throw 1;
}
} catch (const std::runtime_error& e) {
std::cout << "运行时错误:" << e.what() << std::endl;
} catch (int err_code) {
std::cout << "错误码:" << err_code << std::endl;
}

这种按类型区分的方式,让错误处理更有针对性。

别忘了资源管理

有人担心:用了异常,之前申请的资源会不会泄漏?比如打开了文件、分配了内存。其实 C++ 的 RAII(资源获取即初始化)机制天然支持异常安全。只要把资源交给对象管理,比如用 std::fstream 而不是 FILE*,用 std::unique_ptr 管理动态内存,异常发生时析构函数会自动释放资源。

try {
std::ifstream file("config.txt");
std::unique_ptr<int[]> buffer(new int[1024]);
// 如果这里抛异常,file 和 buffer 都会被自动清理
} catch (...) {
std::cout << "出了点事,但资源已经干净了" << std::endl;
}

这里的 catch(...) 表示捕获所有类型的异常,适合做兜底处理。

实际场景中的使用建议

在开发后台服务或桌面软件时,主循环里通常会包一层 try-catch,防止某个请求出错导致整个服务挂掉。比如一个处理用户上传的模块:

用户上传了一个损坏的配置文件,解析时抛出异常。如果没有捕获,程序可能直接终止;加上异常处理后,只需返回“文件格式错误”,其他功能照常运行。

当然,也不是所有地方都适合抛异常。频繁调用的底层函数如果靠异常传错,开销会比较大。这时候用返回码更合适。异常更适合处理“真正异常”的情况——那些不该经常发生、但一旦发生必须处理的问题。