c++ primer plus 第15章友,异常和其他:异常,栈解退15.3.6

c++ primer plus 第15章友,异常和其他:异常,栈解退15.3.6

栈解退15.3.6



栈解退15.3.6

假设 ty块没有直接调用引发异常的函数,而是调用了对引发异常的函数进行调用的函数,则程序流程将从引发异常的函数跳到包含 ty 块和处理程序的函数。这涉及到栈解退(unwinding thestack),下面进行介绍。首先来看一看 C++通常是如何处理函数调用和返回的。C+通常通过将信息放在栈(参见第9章)中来处理函数调用。具体地说,程序将调用函数的指令的地址(返回地址)放到栈中。当被调用的函数执行完毕后,程序将使用该地址来确定从哪里开始继续执行。另外,函数调用将函数参数放到栈中。在栈中,这些函数参数被视为自动变量。如果被调用的函数创建了新的自动变量,则这些变量也将被添加到栈中。如果被调用的函数调用了另一个函数,则后者的信息将被添加到栈中,依此类推。当函数结束时,程序流程将跳到该函数被调用时存储的地址处,同时栈顶的元素被释放。因此,函数通常都返回到调用它的函数,依此类推,同时每个函数都在结束时释放其自动变量。如果自动变量是类对象,则类的析构函数(如果有的话)将被调用。现在假设函数由于出现异常(而不是由于返回)而终止,则程序也将释放栈中的内存,但不会在释放栈的第一个返回地址后停止,而是继续释放栈,直到找到一个位于ty块(参见图15.3)中的返回地址。随后,控制权将转到块尾的异常处理程序,而不是函数调用后面的第一条语句。这个过程被称为栈解退。引发机制的一个非常重要的特性是,和函数返回一样,对于栈中的自动类对象,类的析构函数将被调用。然而,函数返回仅仅处理该函数放在栈中的对象,而trow 语句则处理ty块和 trow之间整个函数调用序列放在栈中的对象。如果没有栈解退这种特性,则引发异常后,对于中间函数调用放在栈中的自动类对象,其析构函数将不会被调用。
在这里插入图片描述

catch(bad hmean & bg)
//startof catch block
bg .mesg();
std::cout <<"Caught in means()\n";
throw;
//rethrows the exception

上述代码显示消息后,重新引发异常,这将向上把异常发送给 main()函数。一般而言,重新引发的异常将由下一个捕获这种异常的 ty-catch 块组合进行处理,如果没有找到这样的处理程序,默认情况下程序将异常终止。程序清单 15.12 使用的头文件与程序清单15.11 使用的相同(程序清单 15.10 所示的 exc_mean.h)。
程序清单15.12 error5.cpp

//error5.cpp -- unwinding the stack
#include <iostream>
#include <cmath> // or math.h, unix users may need -lm flag
#include <string>
#include "exc_mean.h"

class demo
{
   
private:
    std::string word;
public:
    demo (const std::string & str)
    {
   
        
        word = str;
        std::cout << "demo " << word << " created\n"<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值