18

考虑以下代码:

example_t* a = new example_t[8];

example_t具有可以抛出的默认 ctor,假设构造数组中的第 5 个元素会抛出。是否会自动调用前 4 个元素的析构函数?这是一个定义明确的行为吗?

4

2 回答 2

14

这是完美定义且行为良好的。如果对象的初始化以异常终止,则所有完全构造的子对象都将被销毁,其构造顺序与它们的构造相反。这对于数组和用户定义类型的对象(想想类和类成员)是一样的。

形式上,我们有 C++11 15.2/2:

任何存储持续时间的对象,如果其初始化或销毁被异常终止,将为其所有完全构造的子对象(不包括类联合类的变体成员)执行析构函数,也就是说,对于主构造函数 ( 12.6.2) 已完成执行,而析构函数尚未开始执行。

于 2013-10-29T12:26:02.413 回答
9

根据 § 5.3.4 / 8:

new-expression 通过调用分配函数 (3.7.4.1) 来获取对象的存储空间。如果 new 表达式因抛出异常而终止,它可以通过调用释放函数(3.7.4.2) 来释放存储空间。如果分配的类型是非数组类型,则分配函数的名称是 operator new,而释放函数的名称是 operator delete。如果分配的类型是数组类型,则分配函数的名称是 operator new[],而释放函数的名称是 operator delete[]。

它们将被删除,因为释放函数将调用析构函数。

 


我知道依靠编译器的输出是不可信的,但它至少是一个很好的观察:Live Test

于 2013-10-29T12:03:33.447 回答