堆栈展开 是 在运行时从函数调用堆栈中删除函数项的过程。局部对象的销毁顺序与构造顺序相反。
null
堆栈展开通常与 异常处理 在C++中,当发生异常时,函数调用堆栈被线性搜索异常处理程序,并且在函数处理程序栈中移除具有异常处理程序的函数之前的所有条目。因此,如果一个异常没有在同一个函数(抛出异常的地方)中处理,那么异常处理涉及堆栈展开。基本上,堆栈展开是为运行时构造的所有自动对象调用析构函数(每当抛出异常时)的过程。
例如,以下程序的输出为:
CPP
// CPP Program to demonstrate Stack Unwinding #include <iostream> using namespace std; // A sample function f1() that throws an int exception void f1() throw ( int ) { cout << " f1() Start " ; throw 100; cout << " f1() End " ; } // Another sample function f2() that calls f1() void f2() throw ( int ) { cout << " f2() Start " ; f1(); cout << " f2() End " ; } // Another sample function f3() that calls f2() and handles // exception thrown by f1() void f3() { cout << " f3() Start " ; try { f2(); } catch ( int i) { cout << " Caught Exception: " << i; } cout << " f3() End" ; } // Driver Code int main() { f3(); getchar (); return 0; } |
输出
f3() Start f2() Start f1() Start Caught Exception: 100 f3() End
说明:
- 当f1()抛出异常时,它的条目将从函数调用堆栈中删除,因为f1()不包含抛出异常的异常处理程序,所以调用堆栈中的下一个条目将查找异常处理程序。
- 下一个条目是f2()。由于f2()也没有处理程序,因此它的条目也会从函数调用堆栈中删除。
- 函数调用堆栈中的下一个条目是f3()。由于f3()包含异常处理程序,因此会执行f3()内的catch块,最后执行catch块后的代码。
请注意,f1()和f2()中的以下行根本不执行。
cout<<" f1() End "; // inside f1() cout<<" f2() End "; // inside f2()
如果f1()和f2()中有一些本地类对象,那么这些本地对象的析构函数将在堆栈展开过程中被调用。
注: 在Java中,当异常未在同一个函数中处理时,堆栈展开也会发生。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END