LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 250|回复: 0

C++ 中的异常和堆栈展开

[复制链接]
发表于 2024-2-6 22:39:00 | 显示全部楼层 |阅读模式
在 C++ 异常机制中,控制从 throw 语句移至可处理引发类型的第一个 catch 语句。 在到达 catch 语句时,throw 语句和 catch 语句之间的范围内的所有自动变量将在名为“堆栈展开”的过程中被销毁。 在堆栈展开中,执行将继续,如下所示:

控制通过正常顺序执行到达 try 语句。 执行 try 块内的受保护部分。

如果执行受保护部分的过程中未引发异常,将不会执行 try 块后面的 catch 子句。 执行将在关联的 try 块后的最后一个 catch 子句后面的语句上继续。

如果在执行受保护部分的过程中或在受保护的部分调用的任何例程中引发异常(直接或间接),则从通过 throw 操作数创建的对象中创建异常对象。 (这意味着可能涉及复制构造函数。)此时,编译器会在权限更高的执行上下文中查找可处理所引发类型的异常的 catch 子句,或查找可以处理任何类型异常的 catch 处理程序。 按照 catch 处理程序在 try 块后面的显示顺序检查这些处理程序。 如果未找到适当的处理程序,则检查下一个动态封闭的 try 块。 此过程将继续,直到检查最外面的封闭 try 块。

如果仍未找到匹配的处理程序,或者在展开过程中但在处理程序获得控制前发生异常,则调用预定义的运行时函数 terminate。 如果在引发异常后但在展开开始前发生异常,则调用 terminate。

如果找到匹配的 catch 处理程序,并且它通过值进行捕获,则通过复制异常对象来初始化其形参。 如果它通过引用进行捕获,则初始化参数以引用异常对象。 在初始化形参后,堆栈的展开过程将开始。 这包括对与 catch 处理程序关联的 try 块的开头和异常的引发站点之间完全构造(但尚未析构)的所有自动对象的析构。 析构按照与构造相反的顺序发生。 执行 catch 处理程序且程序会在最后一个处理程序之后(即,在不是 catch 处理程序的第一个语句或构造处)恢复执行。 控制只能通过引发的异常进入 catch 处理程序,而绝不会通过 goto 语句或 switch 语句中的 case 标签进入。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表