是否可以在放置新分配的对象上不调用析构函数?

劳拉·阿特金斯(Lorah Attkins)

说我有一个固定的内存缓冲区

char *buffer; 

然后我使用new布局将结构分配到该缓冲区中

struct S
{ 
    std::tuple<int, double, char> m_data; 
    auto getRecord() 
    { 
        return m_data;
    }
};

S *newS = new(buffer + offset)S; 

我知道我应该手动调用此类分配项的析构函数,但是如果不涉及布管/资源管理,可以忽略它吗?换句话说,如果使用缓冲区的类的析构函数没有执行任何操作(类似于~S()上述操作),可以跳过此步骤吗?如果是这种情况,我可以在不破坏先前租户的情况下重用缓冲区吗?

本·沃格特

该标准在3.8节中有一条[basic.life]涉及以下内容的规则

程序可以通过重新使用对象占用的存储空间,或通过为具有非平凡析构函数的类类型的对象显式调用析构函数,来结束任何对象的生命周期。对于具有非平凡析构函数的类类型的对象,在重用或释放该对象占用的存储空间之前,不需要程序显式调用该析构函数但是,如果没有对析构函数的显式调用,或者没有使用delete-expression(5.3.5)释放存储,则不应隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序行为不确定

许多专家一致认为,“依赖于析构函数产生的副作用”过于模糊而无法使用。许多人将其解释为重言式,意思是“如果在未评估析构函数副作用的情况下程序具有未定义的行为,则未能调用析构函数会导致未定义的行为”。请参阅可观察到的行为和未定义的行为-如果不调用析构函数会发生什么?

如果您的类型具有琐碎的析构函数(在您的示例中似乎是这种情况),则调用它(或未能调用它)根本没有效果-呼叫琐碎的析构函数甚至都不会终止对象的寿命。

o类型对象的生存期在以下情况T结束:

  • 如果T是具有非平凡析构函数的类类型,则析构函数调用开始,或者
  • 对象占用的存储空间被释放,或者被未嵌套在其中的对象重用o

也就是说,如果T没有非平凡的析构函数,则结束对象生存期的唯一方法o是释放或重用其存储。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Delete []不调用元素析构函数

对象超出范围后不调用析构函数

是否允许显式调用析构函数,然后将新变量放置在具有固定生命周期的变量上?

放置新的和析构函数

如何阻止析构函数在堆栈分配的对象上被调用?

放置时析构函数-新

为对象分配值时为什么调用构造函数和析构函数

是否可以确保在下一次迭代之前调用循环内局部对象的析构函数?

调用对象的析构函数是否等效于对该对象调用delete?

不调用对象的析构函数是未定义的行为吗?

当包含它的对象调用其析构函数时,unique_ptr是否会取消分配?

C ++:删除对象而不调用析构函数

为什么不调用继承类的析构函数?

使用move构造函数的push_back是否不调用析构函数?

删除数组而不调用析构函数

当将对象作为参数传递时,为什么要调用析构函数但不调用构造函数?

我可以通过deleteLater()将信号分配给旧对象的析构函数中的新对象吗?

在新的放置缓冲区上调用析构函数?

返回的结构调用它自己的析构函数,该析构函数销毁分配的对象

是否在Exit()上调用基本对象析构函数?

如果调用了子类的析构函数,是否可以停止对其基类的析构函数的调用?

C++ 可以使析构函数不调用类成员的析构函数和基类的析构函数吗?

在不调用析构函数、复制或移动的情况下初始化(分配)内存

为什么在声明指向对象的指针时不调用析构函数

在函数调用期间析构对象

是否可以在不调用 std async 的情况下使用阻塞析构函数创建 std 未来?

为什么不调用析构函数?

如果 std::vector 使用移动构造函数将对象重新分配到新内存,那么为什么必须在原始对象上调用析构函数?

std::map 对象析构函数被调用?