说我有一个固定的内存缓冲区
char *buffer;
Run Code Online (Sandbox Code Playgroud)
我使用placement new在缓冲区中分配我的结构
struct S
{
std::tuple<int, double, char> m_data;
auto getRecord()
{
return m_data;
}
};
S *newS = new(buffer + offset)S;
Run Code Online (Sandbox Code Playgroud)
我知道我应该手动调用这些已分配项目的析构函数,但是如果没有涉及bookeeping /资源管理,是否可以省略它?换句话说,如果使用缓冲区的类的析构函数没有执行任何操作(类似于~S()上面的内容),是否可以跳过此步骤?如果是这种情况,我可以重用缓冲区而不破坏以前的租户吗?
Ben*_*igt 14
该标准在3.8节中有一条规则[basic.life]涵盖了这一点:
程序可以通过重用对象占用的存储来结束任何对象的生命周期,或者通过使用非平凡的析构函数显式调用类类型的对象的析构函数来结束任何对象的生命周期.对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数 ; 但是,如果没有显式调用析构函数或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何程序都依赖于析构函数产生的副作用有未定义的行为.
许多专家一致认为"取决于析构函数产生的副作用"太模糊而无用.许多人将其解释为重言式意义"如果程序在未评估析构函数副作用时具有未定义的行为,则无法调用析构函数会导致未定义的行为".请参阅Observable行为和未定义的行为 - 如果我不调用析构函数会发生什么?
如果你的类型有一个简单的析构函数(在你的例子中似乎是这种情况),那么调用它(或者没有调用它)没有任何效果 - 调用一个简单的析构函数甚至不会结束对象的生命.
o类型对象的生命周期在以下情况T结束:
- 如果
T是具有非平凡析构函数的类类型,则析构函数调用将启动,或者- 对象占用的存储被释放,或被未嵌套的对象重用
o.
也就是说,如果T没有非平凡的析构函数,则终止对象生命周期的唯一方法o是释放或重用其存储.