15.3.6 栈解退(2)
下面是程序清单15.10和程序清单15.12组成的程序的运行情况:
程序说明
来看看该程序的运行过程。首先,正如demo类的构造函数指出的,在main( )函数中创建了一个demo对象。接下来,调用了函数means( ),它创建了另一个demo对象。函数means( )使用6和2来调用函数hmean( )和gmean( ),它们将结果返回给means( ),后者计算一个结果并将其返回。返回结果前,means( )调用了d2.show( );返回结果后,函数means( )执行完毕,因此自动为d2调用析构函数:
接下来的输入循环将值6和 6发送给函数means( ),然后means( )创建一个新的demo对象,并将值传递给hmean( )。函数hmean( )引发bad_hmean异常,该异常被means( )中的catch块捕获,下面的输出指出了这一点:
该catch块中的throw语句导致函数means( )终止执行,并将异常传递给main( )函数。语句d2.show( )没有被执行表明means( )函数被提前终止。但需要指出的是,还是为d2调用了析构函数:
这演示了异常极其重要的一点:程序进行栈解退以回到能够捕获异常的地方时,将释放栈中的自动存储型变量。如果变量是类对象,将为该对象调用析构函数。
与此同时,重新引发的异常被传递给main( ),在该函数中,合适的catch块将捕获它并对其进行处理:
接下来开始了第三次输入循环:6和 8被发送给函数means( )。同样,means( )创建一个新的demo对象,然后将6和 8传递给hmean( ),后者在处理它们时没有出现问题。然而,means( )将6和 8传递给gmean( ),后者引发了bad_gmean异常。由于means( )不能捕获bad_gmean异常,因此异常被传递给main( ),同时不再执行means( )中的其他代码。同样,当程序进行栈解退时,将释放局部的动态变量,因此为d2调用了析构函数:
最后,main( )中的bad_gmean异常处理程序捕获了该异常,循环结束: