Exceptions 异常

抓取程序运行中的异常错误
notion image
将正常代码模块,和错误处理模块分开

Assert语句

notion image
  • Debug vs Release
  1. Debug 模式 assert 语句生效 帮助开发者快速发现问题,提供详细的调试信息
  1. Release 模式 assert 语句被移除,不影响其他

抛出异常Exception

如何抛出

notion image
  • 抛出一个对象
    • notion image
      notion image

抛出给调用者,调用者如何处理?

notion image
如果啥也不写,默认是继续向上的caller传递异常
notion image
CatchVectorIndexError的类型的异常
notion image
不怎么管这个异常,一个throw继续向上传
notion image
notion image
  • 会catch所有类型
    • notion image

Catch的对象的匹配类型

notion image
  1. 严格匹配
  1. 能够向上构型
  1. catch(...)
举例第二种的向上构型的异常类型:

标准库已经有的Exception的类型Library

notion image
你可以自己继承这些类,然后自定义派生一些自己的Exception类

new的异常:bad_alloc()

notion image

在构造函数里面,抛出异常

  • 如果编译器在构造函数中收到抛出的异常,析构函数将不会被调用:
当对象构造失败时(即构造函数抛出异常),该对象被认为从未完全构造完成,因此:
  1. 不会调用析构函数
  1. 只会析构已经完全构造好的成员对象
但是并不会释放已经动态分配的内存(所有这种情况有可能导致内存泄漏)
notion image
如何避免上述情况?——RAII
Using smart_pointers
将动态分配内存的管理,封装在一个smart_pointers的对象里面(其实就像vector),然后用这个对象来管理动态内存,相当于以栈管堆 这样,就算Ctor抛出了异常,也会递归调用已经构造的栈中的对象的析构,所以也会析构smart_pointers,就可以让你管理动态内存的释放,避免内存泄漏
notion image

在析构函数里面抛出异常

别这样写………..

在catch的时候一般都是By reference——用引用来获取异常(避免向上构型的时候的截断)

notion image
引用和指针一样,都可以在向上构型的时候避免被切片

Expectation 的向上传递的情况

让我通过具体例子来解释这种情况下的异常传递机制。

示例代码

执行流程

  1. 第二层未匹配时的行为
    1. 堆栈展开(Stack Unwinding)过程
        • Level 3 抛出 MyException
        • Level 2 的 catch 块无法匹配
        • Level 2 函数的栈帧被展开
          • 局部对象按照构造顺序的反序析构
          • 资源被正确释放
        • 异常继续向上传递
        • Level 1 的 catch 块匹配成功并处理异常

    详细说明

    关键点

    1. 资源管理
        • 所有自动变量(栈上对象)会被正确析构
        • RAII模式确保资源释放
        • 析构顺序与构造顺序相反
    1. 执行流程
        • 未匹配的try-catch块会被跳过
        • 函数中try-catch后的代码不会执行
        • 继续向上查找匹配的catch块
    1. 异常安全性
      1. 现代C++推荐做法
        总结:即使中间层(level2)没有匹配的catch块,异常处理机制也会确保:
        1. 所有资源被正确清理
        1. 所有局部对象被正确析构
        1. 异常继续向上传递直到找到匹配的处理程序
        1. 整个过程是安全和可预测的
        这种机制保证了程序的健壮性和资源安全性,是C++异常处理系统的重要特性。
        那么,Question:那么如果向上传递的所有的Caller都没有catch到这个异常,那么这一叠栈的Caller都会被析构?
        是的,如果所有的调用栈(call stack)都没有捕获到异常,程序会继续展开所有栈帧直到 main 函数,如果 main 也没有捕获,程序会调用 std::terminate() 终止程序,跳出main
        Loading...