我正在编写一个模板类,它在内部管理给定类型的数组。像这样:
template<typename T>
class Example {
// ...
private:
T* objects; // allocated in c'tor (array), deleted in d'tor
// ...
};
当我通过objects
删除它时,我想知道C ++是否会调用delete[] objects;
中每个对象的析构函数。
我需要知道这一点,因为我班级中的对象并不总是包含合理的值,因此不应该调用析构函数。
此外,我想知道如果我将T objects[100]
这样的固定大小的数组声明为Example<T>
的一部分,是否会调用析构函数。
答案 0 :(得分:18)
如果T
有析构函数,则delete[]
将调用它。从 5.3.5删除的c ++ 11标准(草案n3337),第6节:
如果delete-expression的操作数值不是空指针值, delete-expression将 为对象或要删除的数组的元素调用析构函数(如果有)。在一个案例中 数组,元素将按地址递减的顺序销毁(即完成的顺序相反) 他们的建设者;见12.6.2)。
当数组未动态分配且数组超出范围(生命周期结束)时,也将为T
数组中的每个元素调用类型T[]
的析构函数。
我需要知道这一点,因为我班级中的对象并不总是包含合理的值,因此不应该调用析构函数。
但是,对象的某个非常重要问题似乎可以获得无法被破坏的状态。
答案 1 :(得分:3)
是的,使用delete[]
时,将为数组中的所有对象调用析构函数。但这应该不是问题,因为当你使用new[]
(你做了,对吗?)来分配它时,构造函数被调用为数组中的所有对象。
如果构造对象可能处于调用析构函数无效的状态,那么对象就会出现严重错误。你需要让析构函数在所有情况下都能正常工作。
答案 2 :(得分:2)
答案是肯定的。调用每个对象的析构函数。
在相关说明中,您应尽量避免使用delete
。使用智能指针(例如,unique_ptr
,shared_ptr
)和STL容器(例如,std :: vector,std :: array)。
答案 3 :(得分:1)
delete[] objects
类似(但不完全相同):
for (i = 0; i < num_of_objects; ++i) {
delete objects[i];
}
由于delete
调用析构函数,您可以期望delete[]
也这样做。
答案 4 :(得分:1)
delete []
会为数组的每个元素调用析构函数。对于成员数组(您的T objects[100]
)也是如此。
您希望将其保留为指针,并为您的模板设计析构函数(以及复制构造函数和复制赋值运算符,请参阅rule of three/five)以处理{{1}指向的“非敏感”值}}
答案 5 :(得分:0)
是的,delete[]
保证在每个对象上调用析构函数。
根据您的使用情况,使用Boost pointer containers或简单的智能指针容器可能会使(指向异常安全)指针集合变得更容易。