我曾经认为在C++中,如果构造函数抛出异常,则不会调用这个“部分构造”类的析构函数。
但在 C++11 中似乎不再如此:我用 g++ 编译了以下代码并打印“X destructor
“到控制台。这是为什么?
#include <exception>
#include <iostream>
#include <stdexcept>
using namespace std;
class X
{
public:
X() : X(10)
{
throw runtime_error("Exception thrown in X::X()");
}
X(int a)
{
cout << "X::X(" << a << ")" << endl;
}
~X()
{
cout << "X destructor" << endl;
}
};
int main()
{
try
{
X x;
}
catch(const exception& e)
{
cerr << "*** ERROR: " << e.what() << endl;
}
}
Output
Standard out:
X::X(10)
X destructor
Standard error:
*** ERROR: Exception thrown in X::X()
委托构造函数确实是一个新功能,引入了新的销毁逻辑。
让我们回顾一下lifetime对象的生命周期:对象的生命周期开始于some构造函数已经完成。 (参见 15.2/2。标准将此称为“主要构造函数”。)在您的情况下,这是构造函数X(int)
。第二个,委托构造函数X()
现在仅充当普通成员函数。在范围展开时,将调用所有完全构造的对象的析构函数,这包括x
.
其含义实际上非常深远:您现在可以将“复杂”工作负载放入构造函数中,并充分利用通常的异常传播,只要您将构造函数委托给另一个构造函数即可。这样的设计可以消除对各种“init”函数的需要,这些函数过去在不希望在常规构造函数中投入太多工作时很流行。
定义您所看到的行为的特定语言是:
[C++11: 15.2/2]:
[..]类似地,如果对象的非委托构造函数
已完成执行并且该对象的委托构造函数因异常退出,将调用该对象的析构函数。[..]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)