C++异常(2) - 栈展开(stack unwinding)

在运行时期间从函数调用栈中删除函数实体,称为栈展开。栈展开通常用于异常处理。在C++中,如果一个异常发生了,会线性的搜索函数调用栈,来寻找异常处理者,并且带有异常处理的函数之前的所有实体,都会从函数调用栈中删除。所以,如果异常没有在抛出它的函数中被处理,则会激活栈展开。

参考下面程序:

[cpp]  view plain  copy
 print ?
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. // 函数f1会抛出一个异常  
  5. void f1() throw (int) {  
  6.   cout<<"\n f1() Start ";  
  7.   throw 100;  
  8.   cout<<"\n f1() End ";  
  9. }  
  10.    
  11. // 调用函数f1  
  12. void f2() throw (int) {  
  13.   cout<<"\n f2() Start ";  
  14.   f1();  
  15.   cout<<"\n f2() End ";  
  16. }  
  17.     
  18. // 调用函数f2,并处理f1()抛上来的异常  
  19. void f3() {  
  20.   cout<<"\n f3() Start ";  
  21.   try {  
  22.     f2();  
  23.   }  
  24.   catch(int i) {  
  25.    cout<<"\n Caught Exception: "<<i;  
  26.   }  
  27.   cout<<"\n f3() End";  
  28. }  
  29.    
  30. // 演示栈展开过程的程序  
  31. int main() {  
  32.   f3();  
  33.   return 0;  
  34. }  
输出结果:
f3() Start
f2() Start
f1() Start
Caught Exception: 100
f3() End

上述程序中, 当函数f1抛出异常后,它的实体会从函数调用栈中删除掉(因为f1中没有包含异常处理代码),然后下一个调用栈的实体用来查找异常处理者。此例子中,下一个实体是f2()。因为f2中也没有包含异常处理代码,则它的实体也会从函数调用栈中移除。下一个实体是f3(). 因为f3包含了异常处理,则f3中的catch代码块会被执行,最后catch代码块后面的代码也会执行。

注意:f1()与f2()中的如下面所示的代码完全没有执行。

//f1()中没有被执行的代码
cout<<"\n f1() End ";
//f2()中没有被执行的代码 
cout<<"\n f2() End ";

另外需要注意的是:如果f1()和f2()中定于了一些局部对象,则在栈展开的过程中,这些局部对象的析构函数会被调用到。这条规则只使用于栈上分配的对象,对于new出来的对象,那还是需要手动delete的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值