C++ 实际销毁对象是否需要运算符delete的销毁形式?
C++20增加了C++ 实际销毁对象是否需要运算符delete的销毁形式?,c++,language-lawyer,c++20,delete-operator,C++,Language Lawyer,C++20,Delete Operator,C++20增加了运算符delete的销毁形式,其区别在于std::destroming_delete_t参数。它使delete表达式在调用操作符delete之前不再销毁对象 其目的是在显式调用对象的析构函数和释放内存之前,允许根据对象的状态定制删除 然而,我不清楚,在实现这样一个操作符时,我是否真的需要销毁这个对象。具体来说,我是否可以拥有一个静态对象池,并将它们分发给用户,这些用户随后可以将它们视为动态分配的对象?这样,在对象上执行的delete表达式只会将其返回到池中,而不会销毁它。例如,以
运算符delete
的销毁形式,其区别在于std::destroming_delete_t
参数。它使delete
表达式在调用操作符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());
}
#包括
结构A{
virtual~A()=默认值;
};
//“常规”动态分配对象
结构B:A{
静态A*create(){
返回新的B();
}
私人:
B()=默认值;
};
//池化的、静态分配的对象
结构C:A{
静态A*create(){
用于(自动和控制:池){
如果(!c.正在使用){
c、 使用中=正确;
返回&c;
}
}
抛出std::bad_alloc();
}
私人:
静态C池[3];
bool in_use=false;
C()=默认值;
void操作符delete(C*C,std::destroming_delete_t){
c->in_use=false;
}
};
C::池[3];
//通过公共界面以相同方式删除它们。
void do_something_和_delete(A*A){
删除一条;
}
int main(){
做某事并删除(B::create());
做某事并删除(B::create());
做某事并删除(C::create());
做某事并删除(C::create());
}
按照定义,销毁删除运算符的目的是为了有效地处理创建和销毁对象的能力,这些对象的解除分配和销毁由于某种原因需要访问对象。它通过防止在使用销毁操作符delete函数对对象调用delete
时自动调用对象的析构函数来实现这一点。然后将(仍然有效)对象传递给销毁操作符delete,以便它可以执行解除分配和销毁业务
其目的不是让语句删除任何内容代码>向用户谎报此语句完成的内容。但是,作为该功能的一个用例(没有virtual
功能的虚拟析构函数)的结果,该功能可以(ab)用于欺骗用户
当对象的析构函数被输入时(或当存储被重用/释放时),对象的生存期结束。如果销毁运算符delete(ab)用于阻止调用该析构函数,则delete
ing对象不会结束其生存期
但是对用户撒谎是个坏主意,你不应该这样做。而覆盖常规虚拟
函数并不是以完全相同的方式“撒谎”?用户不应该关心对象是否“真的”被破坏。从他们的角度来看,他们不允许在删除任何内容之后取消对任何内容的引用代码>在任何情况下。这只是抽象。@yurikilochek:“重写常规虚拟函数不是以完全相同的方式“说谎”吗?”不是。通过声明函数virtual
,您就是在声明重写它的意图。通过重写它,您声明了替换基类版本的意图。在所有情况下,所有相关方的意图都是明确的,当您做出删除任何内容时,没有背信弃义
实际上并没有破坏任何东西
@yurikilochek:“这只是抽象。”这是一个糟糕的抽象,它扭曲了显而易见的代码的含义,使之成为它不是的东西。如果您想要一个接口,在该接口中您可以暂时使用一个对象,然后返回该对象供以后使用,那么就创建该接口。不要仅仅因为技术上可行,就将delete
重构到该机制中。如果您想将智能指针用于此类类型,可以提供将调用返回API的删除程序,而不是覆盖基本语法结构(如delete
)的行为。此问题被标记为语言问题。答案花了很多时间在说教OP是否应该,而没有时间引用标准。这似乎不适合这样一个带标签的问题?如果它是合法的,它会说“是”,因为删除结束对象的生命周期是调用析构函数的(唯一)功能,所以我猜是这样的?@yakadamnevraumont:“没有时间引用标准”这是允许的,因为标准中没有禁止它的内容,你不能说没有什么东西是被禁止的。我的意思是,我可以复制/粘贴关于生命终结的部分,但我不认为这会对任何事情产生实质性影响。