ch16 exception
本文主要总结 cpp 异常的发生与处理。
异常发生时候的资源释放与捕获处理
在异常发生的时候,在抛出异常的点之前的资源会全部调用析构函数被释放,资源的释放总是先创建的后销毁,后创建的先销毁,这是为了避免依赖情况的发生。然后进行 catch
块的查找,在 catch
块查找中遇到匹配的,就执行 catch
块中的代码,在 catch
块中的代码执行完之后, catch
块代码中创建的对象也会被释放,随后程序会返回到 try catch
块之后继续执行。如果没有匹配到合适的 catch
或者在 catch
块中重新抛出异常,那么代码会回到这个函数的调用者,看看调用者能不能处理,如果处理不了,再向上抛出,直到最上层为止。在 catch
块中,能通过 catch(...)
来捕获所有类型的异常。
一旦异常无法处理,程序会立即结束,甚至资源都还来不及释放就结束了。
不抛出异常的函数
在函数声明的时候加上标签 noexcept
,表明当前的函数不会抛出异常,只要程序员认为一个函数不会抛出异常,就可以加上这个标记,编译器会辅助实现这一点。所谓的编译器辅助不是保证这个函数中不会有异常的产生,而是保证这个函数中即使抛出了异常也不向上传播,而是直接终止程序。直接结束的好处是能够快速定位异常所在,因为程序员的本意是这段代码不产生异常,但是现在产生了,所以必须对代码等进行修改,以继续保证这段代码是不抛出异常的。
RAII
RAII
的核心思想是将资源的生命周期与对象的生命周期绑定,通过对象的构造函数获取资源,并在对象的析构函数中释放资源。这样,当对象被创建时,资源就被自动获取,当对象被销毁时,资源就被自动释放。
RAII
的好处在于它提供了一种自动和异常安全的资源管理机制。由于 cpp 中的对象在超出作用域时会自动调用其析构函数,RAII
确保了即使在发生异常的情况下,资源也会被正确地释放,从而避免了资源泄漏和其他资源管理错误。
理解 RAII
的关键在于理解对象的生命周期与资源管理之间的关联。在 RAII
中,资源的获取和释放是通过对象的构造和析构函数自动完成的,因此程序员不需要显式地调用资源释放函数,这简化了资源管理并减少了错误。
智能指针也是 RAII
的一种实践。