根据§15.2/ 2:
被部分构造或部分被毁将对所有其完全构造子对象执行析构函数的对象,也就是,对于其中的构造已经完成执行子对象而析构函数尚未开始执行。
因此应该调用基类析构函数。也就是说,就像我们知道这将清理基类:
#include <iostream>
struct foo
{
~foo()
{
std::cout << "clean" << std::endl;
}
};
struct bar : foo
{
bar()
{ // foo is initialized...
throw 0; // ...so its destructor is run
}
};
int main()
{
try
{
bar b;
}
catch (...)
{
std::cerr << "caught" << std::endl;
}
}
并认为这将清理员:
#include <iostream>
struct foo
{
~foo()
{
std::cout << "clean" << std::endl;
}
};
struct bar
{
~bar()
{ // f has been initialized...
throw 0; // ...so its destructor will run
}
foo f;
};
int main()
{
try
{
bar b;
}
catch (...)
{
std::cerr << "caught" << std::endl;
}
}
这也将清理基类:
#include <iostream>
struct foo
{
~foo()
{
std::cout << "clean" << std::endl;
}
};
struct bar : foo
{
~bar()
{ // foo has been initialized...
throw 0; // ...so its destructor will run
}
};
int main()
{
try
{
bar b;
}
catch (...)
{
std::cerr << "caught" << std::endl;
}
}
这是我对报价的理解。
从内存,如果析构函数抛出会发生什么标准的定义是如此令人难以置信的复杂,一般可怕,没有人永远,永远从析构函数抛出。我也很确定,所有的标准容器都假设析构函数不在行。基本上,虽然我认为在技术上,这是合法的和明确的,但事实是,没有人会这样做,并且有很好的理由,所以千万不要这样做。 – Puppy 2010-12-22 11:29:00
您在那里的示例应该没有问题。 d正在以正常的方式超出范围。如果事情可能会变得糟糕,如果原因d被破坏,堆栈正在处理另一个异常的一部分。这就是导致关于从不投入析构函数的经验法则的可能性。 – 2010-12-22 11:36:09