考虑以下代码:
example_t* a = new example_t[8];
类example_t
具有可以抛出的默认ctor,假设数组中第5个元素的构造抛出。是否有自动调用4个第一个元素的析构函数?这是一个定义明确的行为吗?
答案 0 :(得分:14)
这是非常明确和良好的行为。如果对象的初始化以与构造相反的顺序终止,则会破坏所有完全构造的子对象。对于数组而言,这与用户定义类型的对象(想想类和类成员)相同。
形式上,我们有C ++ 11 15.2 / 2:
任何存储持续时间的对象,其初始化或销毁由异常终止 为所有完全构造的子对象执行析构函数(不包括a的变体成员) 类似于union的类,也就是主要构造函数(12.6.2)已完成执行的子对象 析构函数尚未开始执行。
答案 1 :(得分:9)
根据§5.3.4/ 8:
new-expression通过调用获取对象的存储空间 分配功能(3.7.4.1)。 如果new-expression终止 抛出异常,可以通过调用a来释放存储空间 解除分配职能(3.7.4.2)。如果分配的类型是非数组 类型,分配函数的名称是operator new和 deallocation函数的名称是operator delete。如果是分配的类型 是一个数组类型,分配函数的名称是operator new []和 释放函数的名称是operator delete []。
它们将被删除,因为释放函数将调用析构函数。
我知道依靠编译器的输出是不可靠的,但它至少是一个很好的观察:Live Test