我有以下代码:
#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;
}
}
}
我看到一组 ~Foo()
在有 try{} catch{}
block 时执行。如果没有异常处理程序,则不会打印任何内容。这是否意味着在处理异常时调用堆栈分配对象的析构函数?或者由于 std::cerr 缓冲问题而没有打印任何内容?
最佳答案
以下是 C++03 标准的详细信息。
从 15.3/9 开始处理异常
If no matching handler is found in a program, the function terminate() is called;
从18.6.3异常终止:
The implementation’s default terminate_handler calls abort().
并从 3.6.3/4 终止:
Calling the function
void abort();
declared in<cstdlib>
terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit().
这就是为什么你的 foos
对象未被破坏(它具有静态存储持续时间)。但是,即使您将其更改为局部变量(具有自动持续时间),也可能无法解决问题(强调):
所以对于 static duration
对象,除非您更改终止处理程序(可能让它调用 exit()
而不是 abort()
),否则不会调用析构函数。但是,对于自动对象,仍然存在一个可能的问题(强调):
15.5.1/1 The
terminate()
functionIn the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before terminate() is called. In all other situations, the stack shall not be unwound before terminate() is called.
关于c++ - 为什么在 main 中未捕获异常时不调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8553357/