13

这里的“简单”是指具有非虚拟空析构函数或 POD 类型的类。

典型例子:

char buffer[SIZE];
T *p = new(buffer) T;
...
p->~T();  // <---- always ?

如果我们不调用显式析构函数 on 会发生什么p?我不认为这是未定义的行为或内存泄漏。
重复使用有什么问题buffer吗?

4

4 回答 4

12

从技术上讲,假设析构函数不释放构造过程中获取的任何资源,则可能没有必要。

但是,考虑到非技术方面 - 代码的维护和演变 - 我会坚持最佳实践 - 构建的内容应该被破坏。需要考虑的场景 - 如果将来某些更改将决定相关代码放入析构函数中怎么办?你会记得你对那种类型的对象的破坏持怀疑态度吗?

于 2012-05-11T06:54:58.120 回答
10

对于 POD 类型或具有微不足道的析构函数的类:否。当对象的存储被释放或重用时,对象的生命周期将结束。如果您不想,则不必显式调用析构函数。

也就是说,没有理由不这样做。对于具有普通析构函数的类型,析构函数调用不会生成任何代码。

如果通过具有“空”析构函数的类,您允许该类具有具有非平凡析构函数的成员或基类,那么如果您的程序依赖于调用这些析构函数,您可能会得到未定义的行为。

请注意,用户提供的析构函数是一个重要的析构函数,即使它是非虚拟的并且是空的。尽管如此,您仍然可以通过简单地释放或重用其存储空间来结束具有此类析构函数的对象的生命周期,前提是您的程序不依赖于析构函数的任何副作用。(参见 ISO/IEC 14882:2011 的 3.8 [basic.life] / 4)

于 2012-05-11T06:57:29.233 回答
1

如果您的类处理一些资源(堆内存、句柄、计数器、互斥体...)或包含一些处理资源的字段,如果您不显式调用析构函数,这些资源将不会被释放。否则没有任何破坏的麻烦。您可以将未破坏的类视为内存中的垃圾,并在同一位置自由构建新的类。

于 2012-05-11T06:55:37.373 回答
0

是的,您必须显式调用析构函数(请记住 T 的副作用,即释放一些额外的内存)。此外,在使用placement new 时,您必须注意内存对齐。

如果您愿意,您可以重用缓冲内存。

另请参阅http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

于 2012-05-11T06:57:44.927 回答