删除[]调用析构函数
Does delete[] call destructors?
我正在编写一个模板类,它在内部管理给定类型的数组。像这样:
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_ptr
、shared_ptr
)和STL容器(例如,std::vector、std::array)。
delete[] objects
与类似(但不相同)
for (i = 0; i < num_of_objects; ++i) {
delete objects[i];
}
由于delete
调用析构函数,因此可以预期delete[]
也会这样做。
delete[]
保证对每个对象调用析构函数。
根据您的用例,使用Boost指针容器,或者只是智能指针的容器,可能会使指针的集合(异常安全)变得容易得多。
- 析构函数调用
- 在具有向量的类构造函数中进行析构函数调用
- 从 c++ 中派生类的析构函数调用虚函数
- C++析构函数调用两次,堆栈分配的复合对象
- C++ 在析构函数调用之前删除的动态成员数组
- 析构函数调用c++中的一个向量
- Singleton模式中的手动析构函数调用:调用多次
- 从内部类的析构函数调用虚拟函数
- 与 boost odeint 集成期间的析构函数调用
- 堆栈展开如何与析构函数调用有关?
- C++:优化析构函数调用
- 以逗号分隔的表达式中的析构函数调用
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 从C++中的虚拟析构函数调用虚拟方法
- 从指针返回对象时出现意外的析构函数调用
- 使用 decltype 显式析构函数调用
- C++析构函数调用了错误的对象
- 了解虚拟函数和析构函数调用
- 多重继承析构函数调用他自己和父析构函数?c++
- 析构函数调用表单不适当的库