c++ 20增加了用std::destroying_delete_t
参数来区分operator delete
的销毁形式。它使delete
表达式在调用operator delete
之前不再破坏对象。
目的是允许在显式调用对象的析构函数和释放内存之前,以一种依赖于对象状态的方式自定义删除。
然而,我不清楚,在实现这样一个操作符时,我是否真的需要销毁对象。具体来说,我是否可以拥有一个静态对象池,并将它们分配给随后可以将它们视为动态分配的用户?这样,在对象上执行的delete
表达式只会将对象返回到池中,而不会销毁它。例如,下面的程序定义良好吗?
#include <new>
struct A {
virtual ~A() = default;
};
// 'Regular' dynamically allocated objects
struct B : A {
static A* create() {
return new B();
}
private:
B() = default;
};
// Pooled, statically allocated objects
struct C : A {
static A* create() {
for (auto& c: pool) {
if (!c.in_use) {
c.in_use = true;
return &c;
}
}
throw std::bad_alloc();
}
private:
static C pool[3];
bool in_use = false;
C() = default;
void operator delete(C *c, std::destroying_delete_t) {
c->in_use = false;
}
};
C C::pool[3];
// Delete them identically via the common interface.
void do_something_and_delete(A* a) {
delete a;
}
int main() {
do_something_and_delete(B::create());
do_something_and_delete(B::create());
do_something_and_delete(C::create());
do_something_and_delete(C::create());
}
销毁删除操作符的目的,按照其建议的定义,是为了有效地处理创建和销毁对象的能力,这些对象的解除分配和销毁由于某种原因需要访问该对象。它通过防止在使用销毁操作符delete函数对对象调用delete
时自动调用对象的析构函数来实现这一点。然后将(仍然存在的)对象传递给销毁操作符delete,这样它就可以执行释放和销毁操作。
它的目的是而不是使语句delete whatever;
对用户撒谎。但是作为该特性的一个用例(没有virtual
函数的虚析构函数)的结果,该特性可以(ab)用来欺骗用户。
对象的生命周期在其析构函数进入时结束(或在存储被重用/释放时结束)。如果使用了析构操作符delete (ab)来防止调用该析构函数,则对象的delete
将不会结束其生命周期。
但是对用户撒谎是一个坏主意,你不应该这样做。