16

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

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

我想知道objects当我通过delete[] objects;.

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

此外,我想知道如果我声明一个固定大小的数组(T objects[100]Example<T>.

4

6 回答 6

30

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

如果 delete-expression 的操作数的值不是空指针值,则 delete-expression 将为要删除的对象或数组的元素调用析构函数(如果有)。在数组的情况下,元素将按照地址递减的顺序被销毁(即,按照它们的构造函数完成的相反顺序;参见 12.6.2)。

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


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

但是,一个对象似乎有一个非常重要的问题,它可以获取一个不能被破坏的状态。

于 2013-06-27T13:43:52.093 回答
3

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

如果构造的对象可能处于调用析构函数无效的状态,那么您的对象存在严重错误。你需要让你的析构函数在所有情况下都能工作。

于 2013-06-27T13:43:40.253 回答
2

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

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

因为delete调用了析构函数,你可以期望delete[]做同样的事情。

于 2013-06-27T13:43:35.107 回答
2

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

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

于 2013-06-27T13:43:54.083 回答
1

delete []确实为数组的每个元素调用析构函数。成员数组(您的T objects[100])也会发生同样的情况。

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

于 2013-06-27T13:43:43.107 回答
0

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

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

于 2013-06-27T13:48:50.370 回答