try语句块和异常处理

throw后面紧跟一个表达式,表达式类型就是抛出异常的类型

try语句块

program-statements里面放正常的程序逻辑,一旦执行到throw语句,就中断正常的程序,开始寻找匹配的catch

catch语句

抛出异常

throw抛出异常,后面的语句不再执行,跳转到与之匹配的catch模块

栈展开就是在程序抛出异常后,沿着函数调用链一层层往回找,找到包住throw语句的try和相匹配的能处理异常的catch代码的过程。如果找到了就处理,找不到就程序崩溃。

在栈展开的过程中,调用链上退出的函数中创建的局部对象会被自动销毁。每退出一层函数、一个代码块,里面的局部变量(对象)就会像正常离开作用域一样被销毁。

析构函数总是会被执行的,但是函数中负责释放资源的代码却可能被跳过,如果一个块分配了资源,并且在负责释放这些资源的代码(delete)前面发生了异常,则释放资源的代码将不会被执行。

异常对象

当使用 throw 抛出一个异常时,其实是创建了一个特殊的对象,叫做"异常对象"。

1.throw 会"拷贝"那个异常值(不是原样扔出去,而是拷贝/移动一份);
2.这份异常对象会放到一个专门由编译器管理的内存空间里,确保后续 catch 能访问;
3.一旦异常处理完毕,这个异常对象会被自动销毁;
4.如果抛出的东西是一个类对象,它的构造函数、析构函数、拷贝/移动构造函数都必须是可访问的,不然编译器会报错。

不要抛指针指向局部对象,局部对象在栈展开退出代码块时就会销毁,导致捕获空悬指针

对象切片:类继承中,静态编译时类型决定了异常对象的类型,即如果抛出的基类对象指针是用派生类赋值的,只会复制并抛出基类部分。