实际销毁对象是否需要销毁 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)用于防止调用该析构函数,那么 deleteing 对象将不会结束其生命周期。

但是对用户说谎是个坏主意,你不应该这样做。