实际销毁对象是否需要销毁 operator delete 形式?
Is destroying form of operator delete required to actually destroy the object?
C++20 添加了 operator delete
的破坏形式,由 std::destroying_delete_t
参数区分。它导致 delete
表达式在调用 operator delete
.
之前不再销毁对象
目的是允许在显式调用对象的析构函数和释放内存之前,以依赖于对象状态的方式自定义删除。
但是,我不清楚在实现这样的运算符时,我是否真的需要销毁该对象。具体来说,我是否可以拥有一个静态对象池,并将它们分发给随后可以将它们视为动态分配的用户?这样在对象上执行的 delete
表达式只会 return 它到池中而不破坏它。例如,下面的程序是否定义良好?
#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());
}
如 by its proposal 所定义,销毁删除运算符的目的是为了有效地处理创建和销毁对象的能力,这些对象的释放和销毁需要访问对象,无论出于何种原因。它通过在使用销毁运算符 delete 函数对对象调用 delete
时阻止自动调用对象的析构函数来实现这一点。然后将(仍然存在的)对象传递给销毁运算符 delete,以便它可以执行释放和销毁业务。
它的目的是而不是使声明delete whatever;
向用户谎报该声明的作用。但由于该功能的一个用例(没有 virtual
函数的虚拟析构函数),该功能可能被(滥用)用来欺骗用户。
一个对象的生命周期在进入其析构函数时结束(或当存储reused/released)。如果破坏性运算符 delete 被(ab)用于防止调用该析构函数,那么 delete
ing 对象将不会结束其生命周期。
但是对用户说谎是个坏主意,你不应该这样做。
C++20 添加了 operator delete
的破坏形式,由 std::destroying_delete_t
参数区分。它导致 delete
表达式在调用 operator delete
.
目的是允许在显式调用对象的析构函数和释放内存之前,以依赖于对象状态的方式自定义删除。
但是,我不清楚在实现这样的运算符时,我是否真的需要销毁该对象。具体来说,我是否可以拥有一个静态对象池,并将它们分发给随后可以将它们视为动态分配的用户?这样在对象上执行的 delete
表达式只会 return 它到池中而不破坏它。例如,下面的程序是否定义良好?
#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());
}
如 by its proposal 所定义,销毁删除运算符的目的是为了有效地处理创建和销毁对象的能力,这些对象的释放和销毁需要访问对象,无论出于何种原因。它通过在使用销毁运算符 delete 函数对对象调用 delete
时阻止自动调用对象的析构函数来实现这一点。然后将(仍然存在的)对象传递给销毁运算符 delete,以便它可以执行释放和销毁业务。
它的目的是而不是使声明delete whatever;
向用户谎报该声明的作用。但由于该功能的一个用例(没有 virtual
函数的虚拟析构函数),该功能可能被(滥用)用来欺骗用户。
一个对象的生命周期在进入其析构函数时结束(或当存储reused/released)。如果破坏性运算符 delete 被(ab)用于防止调用该析构函数,那么 delete
ing 对象将不会结束其生命周期。
但是对用户说谎是个坏主意,你不应该这样做。