一、背景
C++的异常处理机制是用来处理程序运行过程中出现的异常情况的。异常处理可以帮助程序应对错误,避免程序崩溃,并且可以提供有意义的错误信息。下面是C++异常处理的关键概念和常用模式的总结。
二、异常处理
1. 异常处理的基本机制
C++使用try, catch, 和throw关键字来实现异常处理。
- throw: 用于抛出异常。
- try: 用于捕获异常的代码块。
- catch: 用于处理异常。
try {
// 可能会抛出异常的代码
if (something_went_wrong) {
throw std::runtime_error("An error occurred");
}
} catch (const std::exception& e) {
// 处理异常的代码
std::cerr << "Caught exception: " << e.what() << std::endl;
}
2. 异常类型
C++允许抛出和捕获任何类型的异常,但通常使用标准库中的异常类,如std::exception
及其派生类。这些类提供了标准化的异常处理接口。
常用的异常类包括:
std::exception
: 所有标准异常的基类。std::runtime_error
: 用于报告运行时错误。std::logic_error
: 用于报告逻辑错误。std::out_of_range
: 用于报告越界错误。std::bad_alloc
: 用于报告内存分配错误。
3. 自定义异常类
可以定义自己的异常类,通常继承自std::exception
或其派生类。
class MyException : public std::exception {
public:
const char* what() const noexcept override {
return "My custom exception message";
}
};
4. 异常安全性
C++代码应尽量保持异常安全性,即使抛出异常也应确保程序的状态保持一致。异常安全性通常分为以下几种级别:
- 基本保证: 即使发生异常,对象的状态也保持有效。
- 强保证: 如果异常发生,程序状态将回到异常发生前的状态。
- 无异常保证: 执行的操作保证不会抛出异常。
5. RAII 和智能指针
资源获取即初始化(RAII)是一种常见的管理资源的技术,结合智能指针使用可以有效管理资源,避免资源泄漏。
void func() {
std::unique_ptr<int> ptr(new int(10)); // RAII, 自动管理内存
// 其他代码,可能会抛出异常
} // ptr超出作用域,自动释放内存
6. 标准库中的异常辅助工具
C++标准库提供了许多辅助工具来简化异常处理,包括std::exception_ptr
和std::nested_exception
等。
std::exception_ptr
用于捕获和存储异常,方便在不同线程之间传递异常。
std::exception_ptr eptr;
try {
// 可能抛出异常的代码
} catch (...) {
eptr = std::current_exception(); // 捕获当前异常
}
if (eptr) {
try {
std::rethrow_exception(eptr); // 重新抛出异常
} catch (const std::exception& e) {
std::cerr << &#