说我有一个固定的内存缓冲区
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] 删除。
我来说两句