为什么 new[] 表达式会调用析构函数?
Why would a new[] expression ever invoke a destructor?
来自C++17标准(草案here),[expr.new]:
If the new-expression creates an object or an array of objects of class type, access and ambiguity control are done for the allocation function, the deallocation function, and the constructor. If the new-expression creates an array of objects of class type, the destructor is potentially invoked.
为什么 new[]
会调用析构函数?毕竟是 新的,。它不是 删除。
如果缓冲区中任何对象的构造抛出异常,则必须销毁先前构造的对象。这需要一个可用的析构函数。
您没有考虑您在标准中提到的引文中的 "potentially" 这个词。
这意味着有可能调用析构函数。 如果数组中任何对象的构造抛出异常,就会发生。
结合以下引自 [class.dtor]/12.4
的引用 [expr.new]
,这就很清楚了。
In each case, the context of the invocation is the context of the construction of the object. A destructor is also invoked implicitly through use of a delete-expression for a constructed object allocated by a new-expression; the context of the invocation is the delete-expression. [ Note: An array of class type contains several subobjects for each of which the destructor is invoked. — end note ] A destructor can also be invoked explicitly. A destructor is potentially invoked if it is invoked or as specified in [expr.new]
, [class.base.init]
, and [except.throw]
. A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
进行中:
#include <iostream>
int counter;
class Destruct
{
public:
Destruct()
{
if (counter++ > 5)
throw counter;
}
~Destruct()
{
std::cout << "Dtor called\n";
}
};
int main()
{
try
{
new Destruct[10];
}
catch (...){}
}
您会看到如下输出:
Dtor called
Dtor called
Dtor called
Dtor called
Dtor called
Dtor called
来自C++17标准(草案here),[expr.new]:
If the new-expression creates an object or an array of objects of class type, access and ambiguity control are done for the allocation function, the deallocation function, and the constructor. If the new-expression creates an array of objects of class type, the destructor is potentially invoked.
为什么 new[]
会调用析构函数?毕竟是 新的,。它不是 删除。
如果缓冲区中任何对象的构造抛出异常,则必须销毁先前构造的对象。这需要一个可用的析构函数。
您没有考虑您在标准中提到的引文中的 "potentially" 这个词。
这意味着有可能调用析构函数。 如果数组中任何对象的构造抛出异常,就会发生。
结合以下引自 [class.dtor]/12.4
的引用 [expr.new]
,这就很清楚了。
In each case, the context of the invocation is the context of the construction of the object. A destructor is also invoked implicitly through use of a delete-expression for a constructed object allocated by a new-expression; the context of the invocation is the delete-expression. [ Note: An array of class type contains several subobjects for each of which the destructor is invoked. — end note ] A destructor can also be invoked explicitly. A destructor is potentially invoked if it is invoked or as specified in
[expr.new]
,[class.base.init]
, and[except.throw]
. A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
进行中:
#include <iostream>
int counter;
class Destruct
{
public:
Destruct()
{
if (counter++ > 5)
throw counter;
}
~Destruct()
{
std::cout << "Dtor called\n";
}
};
int main()
{
try
{
new Destruct[10];
}
catch (...){}
}
您会看到如下输出:
Dtor called
Dtor called
Dtor called
Dtor called
Dtor called
Dtor called