ban*_*nov 2 c++ destructor exception stack-unwinding
我有以下代码:
#include <iostream>
#include <vector>
#include <tr1/memory>
struct FooError {};
struct Foo
{
~Foo() { std::cerr << "~Foo() executed" << std::endl; }
explicit Foo(unsigned int index) { if (5 == index) throw FooError(index); };
};
int main() {
typedef std::tr1::shared_ptr<Foo> FooPtr;
std::vector<FooPtr> foos;
for (unsigned int index = 0; index < 20; ++index)
{
try
{
foos.push_back(FooPtr(new Foo(index)));
}
catch (const FooError&)
{
std::cerr << "FooError caught" << std::endl;
}
}
}
Run Code Online (Sandbox Code Playgroud)
~Foo()当有try{} catch{}块时我看到一组被执行.如果没有异常处理程序,则不会打印任何内容.是否意味着在处理异常时会调用堆栈分配对象的析构函数?或者因为std :: cerr缓冲问题而没有打印出来?
以下是C++ 03标准的详细信息.
从15.3/9处理异常
如果在程序中找不到匹配的处理程序,则调用函数terminate();
从18.6.3异常终止:
实现的默认terminate_handler调用abort().
从3.6.3/4终止:
调用
void abort();声明的函数会<cstdlib>终止程序,而不会为自动或静态存储持续时间的对象执行析构函数,也不会调用传递给atexit()的函数.
这就是为什么你的foos对象没有被破坏(它有静态存储持续时间).但是,即使您更改它以使其成为局部变量(具有自动持续时间),也可能无法解决问题(强调添加):
因此,对于static duration对象,除非您更改终止处理程序(可能是为了调用exit()而不是abort()),否则不会调用析构函数.但是,对于自动对象,仍然存在可能的问题(强调添加):
15.5.1/1
terminate()功能在没有找到匹配处理程序的情况下,无论堆栈是否在调用terminate()之前展开,它都是 实现定义的.在所有其他情况下,在调用terminate()之前不应解开堆栈.