我们是否需要为分配"placement new" "simple POD classes"显式调用析构函数?
Do we need to explicitly call the destructor for the "simple POD classes" allocated with "placement new"?
这里的"简单",我的意思是具有非虚拟空析构函数或 POD 类型的类。
典型例子:
char buffer[SIZE];
T *p = new(buffer) T;
...
p->~T(); // <---- always ?
如果我们不对p
调用显式析构函数会发生什么?我不认为这是未定义的行为或内存泄漏。
重用buffer
有问题吗?
从技术上讲,假设析构函数不释放在构造过程中获得的任何资源,则可能没有必要。
但是,考虑到非技术方面 - 代码的维护和演变 - 我会坚持最佳实践 - 构建的内容应该被破坏。要考虑的方案 - 如果将来某些更改将确定要放入析构函数中的相关代码怎么办?你会记得你一直破坏那种类型的物体吗?
对于 POD 类型或具有简单析构函数的类:否。对象的生存期将在释放或重用对象的存储时结束。如果您不想,则不必显式调用析构函数。
也就是说,没有理由不这样做。对于具有简单析构函数的类型,析构函数调用不会生成任何代码。
如果通过具有"空"析构函数的类,您允许该类具有具有非平凡析构函数的成员或基类的可能性,那么如果您的程序依赖于调用的这些析构函数,则可能会获得未定义的行为。
请注意,用户提供的析构函数是非平凡析构函数,即使它是非虚拟的并且为空。尽管如此,您仍然可以通过简单地释放或重用其存储来结束使用此类析构函数结束对象的生存期,前提是您的程序不依赖于析构函数的任何副作用。(参见ISO/IEC 14882:2011的3.8 [basic.life]/4(
如果您的类处理某些资源(堆内存、句柄、计数器、互斥体...(或包含一些处理资源的字段,则如果不显式调用析构函数,则不会释放此资源。否则,没有任何破坏的麻烦。您可以将非析构类视为内存中的垃圾,并在同一位置自由构造新类。
是的,你必须显式调用析构函数(请记住 T 的副作用,即释放一些额外的内存(。此外,在使用放置 new 时,您必须小心内存对齐。
如果您愿意,可以重用缓冲区内存。
另请参阅 http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 如何在 malloc 内存中初始化非 POD 数据
- 使用 std::index_sequence 初始化具有固定大小数组成员的 POD 结构容器
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- 带有 char[] 字段的 POD 结构的 constexpr 构造
- 非 POD 的零初始化
- C++定义构造函数使对象成为非 POD
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- Threads with Classes and std::packaged_task
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- 具有非 POD 对象的 GLib 异步队列
- 约束类模板函数以接受特定的 POD 类型
- 从基本类型转换为非 POD 结构
- 我可以说服自动生成的构造函数将我的 POD 类成员归零吗?
- 根据 MSVC,具有易失性成员的结构不再是 POD
- 快速将无符号字符的向量强制转换为POD结构的向量,反之亦然
- POD类型是否完全等同于琐碎的标准布局类型
- 如何创建非 POD 类型的连续内存池?
- 如何让MSVC编译器优化多步POD初始化?
- 我们是否需要为分配"placement new" "simple POD classes"显式调用析构函数?