在放置新分配的对象时不调用析构函数可以吗?

2023-12-30

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

char *buffer; 

And I 使用placement 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]这涵盖了这一点:

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

许多专家一致认为“取决于析构函数产生的副作用”太模糊而无用。许多人将其解释为同义反复,意思是“如果在未评估析构函数副作用时程序有未定义的行为,则未能调用析构函数会导致未定义的行为”。看可观察的行为和未定义的行为——如果我不调用析构函数会发生什么? https://stackoverflow.com/q/21110059/103167

如果您的类型有一个简单的析构函数(在您的示例中似乎是这种情况),那么调用它(或未能调用它)没有任何效果 - 调用一个简单的析构函数甚至不会结束对象的生命。

对象的生命周期o类型的T结束时间:

  • if T是具有非平凡析构函数的类类型,析构函数调用开始,或者
  • 对象占用的存储被释放,或者被未嵌套的对象重用o.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在放置新分配的对象时不调用析构函数可以吗? 的相关文章

随机推荐