删除[]调用析构函数

Does delete[] call destructors?

本文关键字:析构函数 调用 删除      更新时间:2023-10-16

我正在编写一个模板类,它在内部管理给定类型的数组。像这样:

template<typename T>
class Example {
    // ...
private:
    T* objects; // allocated in c'tor (array), deleted in d'tor
    // ...
};

当我通过delete[] objects;删除它时,我想知道C++是否调用了objects中每个对象的析构函数。

我需要知道这一点,因为我的类中的对象并不总是包含合理的值,所以当析构函数不包含时,就不应该调用它们。

此外,我想知道如果我声明了一个固定大小的数组(如T objects[100])作为Example<T>的一部分,是否会调用析构函数。

如果T有析构函数,那么它将由delete[]调用。从第5.3.5节删除c++11标准(草案n3337)第6条:

如果删除表达式的操作数值不是空指针值,则删除表达式将调用要删除的对象或数组元素的析构函数(如果有的话)。在数组中,元素将按地址递减的顺序(即按完成的相反顺序)销毁建造商;见12.6.2)。

当未动态分配数组并且数组超出范围(生存期结束)时,类型T的析构函数也将为T[]数组中的每个元素调用。


我需要知道这一点,因为我的类中的对象并不总是包含合理的值,所以当析构函数不包含时,就不应该调用它们。

但是,对于一个可以获取无法销毁状态的对象,似乎存在一个非常严重的问题。

是的,当使用delete[]时,将为数组中的所有对象调用析构函数。但这不应该是个问题,因为当你使用new[](你这样做了,对吧?)来分配它时,构造函数是为数组中的所有对象调用的

如果构造的对象处于调用析构函数无效的状态,那么您的对象就出现了严重的问题。你需要让你的析构函数在任何情况下都能工作。

delete []确实为数组的每个元素调用析构函数。成员数组(您的T objects[100])也是如此。

您希望将其保留为指针,并为模板设计析构函数(以及复制构造函数和复制赋值运算符,请参见三五规则),以处理objects指向的"不明智"值。

答案是肯定的。调用每个对象的析构函数。

与此相关的是,您应该尽可能避免使用delete。请改用智能指针(例如,unique_ptrshared_ptr)和STL容器(例如,std::vector、std::array)。

delete[] objects与类似(但不相同)

for (i = 0; i < num_of_objects; ++i) {
    delete objects[i];
}

由于delete调用析构函数,因此可以预期delete[]也会这样做。

是的,delete[]保证对每个对象调用析构函数。

根据您的用例,使用Boost指针容器,或者只是智能指针的容器,可能会使指针的集合(异常安全)变得容易得多。