异常处理通过try-catch提升C++程序稳定性与可维护性;2. try块包含可能抛出异常的代码,catch块捕获并处理特定类型异常或所有异常;3. 示例中抛出std::runtime_error并由const std::exception&捕获,避免程序崩溃。

在C++中,异常处理是编写健壮代码的重要手段之一。通过合理使用try-catch机制,程序可以在出现错误时优雅地恢复或终止,而不是直接崩溃。这不仅提升了程序的稳定性,也增强了可维护性。
理解try-catch基本结构
try-catch用于捕获和处理运行时可能发生的异常。try块中包含可能抛出异常的代码,catch块则负责处理这些异常。
- try块不能单独存在,必须后跟至少一个catch或finally(C++无finally,可用RAII替代)
- catch可以捕获特定类型的异常,如int、string,也可以捕获标准异常std::exception及其派生类
- 使用...可以捕获所有异常,但应谨慎使用,避免掩盖关键问题
示例:
try {
if (error_occurred) {
throw std::runtime_error("Something went wrong");
}
}
catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown exception caught" << std::endl;
}
优先使用标准异常和自定义异常类
C++标准库提供了丰富的异常类型,如std::invalid_argument、std::out_of_range等。在自定义逻辑中,建议从std::exception派生自己的异常类,以便统一处理。
立即学习“C++免费学习笔记(深入)”;
- 继承std::runtime_error或std::logic_error更方便,它们已实现what()方法
- 为不同模块定义不同的异常类型,有助于定位问题来源
- 确保异常类是可复制的,并且what()返回的字符串生命周期安全
例如:
class FileOpenError : public std::runtime_error {
public:
explicit FileOpenError(const std::string& filename)
: std::runtime_error("Cannot open file: " + filename) {}
};
异常安全的三大保证级别
编写异常安全代码时,需考虑以下三个层次的保证:
- 基本保证:操作失败后,对象仍处于有效状态,无资源泄漏
- 强保证:操作要么完全成功,要么回到调用前状态(类似事务)
- 不抛异常保证:操作一定不会抛出异常,常用于析构函数和swap
实现方式包括使用RAII(Resource Acquisition Is Initialization),将资源管理封装在对象中,如std::unique_ptr、std::lock_guard等,确保即使抛出异常也能正确释放资源。
避免在析构函数中抛出异常
如果一个正在处理异常的过程中又抛出新异常(即栈展开期间),程序会直接调用std::terminate()终止执行。因此,析构函数应尽量避免抛出异常。
- 析构函数中可能发生异常的操作应被包裹在try-catch内并妥善处理
- 记录日志或忽略错误比传播异常更安全
例如:
~MyClass() {
try {
close_resource();
}
catch (...) {
// 记录错误,但不重新抛出
}
}
总结:合理使用try-catch、遵循异常安全准则、结合RAII模式,能显著提升C++程序的健壮性。异常不是错误,而是程序流的一部分,正确处理它,才能写出可靠、易调试的代码。基本上就这些。











