当前位置: 首页 > 知识库问答 >
问题:

什么是C++20中的“销毁删除”?

郎曾笑
2023-03-14

C++20引入了“destroyingdelete”(带有标记类型std::destroying_delete_t),是运算符delete的新重载。

这到底是什么,什么时候有用?

共有1个答案

程谦
2023-03-14

在C++20之前,对象的析构函数总是在调用其运算符delete之前调用。通过在C++20中销毁delete运算符delete可以调用析构函数本身。下面是一个非常简单的不销毁与销毁delete的玩具示例

#include <iostream>
#include <new>

struct Foo {
    ~Foo() {
        std::cout << "In Foo::~Foo()\n";
    }

    void operator delete(void *p) {
        std::cout << "In Foo::operator delete(void *)\n";
        ::operator delete(p);
    }
};

struct Bar {
    ~Bar() {
        std::cout << "In Bar::~Bar()\n";
    }

    void operator delete(Bar *p, std::destroying_delete_t) {
        std::cout << "In Bar::operator delete(Bar *, std::destroying_delete_t)\n";
        p->~Bar();
        ::operator delete(p);
    }
};

int main() {
    delete new Foo;
    delete new Bar;
}

和输出:

In Foo::~Foo()
In Foo::operator delete(void *)
In Bar::operator delete(Bar *, std::destroying_delete_t)
In Bar::~Bar()

关于它的关键事实:

    null
  • 销毁delete允许末尾有可变大小数据的类保留有大小的delete的性能优势。这是通过在对象中存储大小,并在调用析构函数之前在运算符delete中检索它来实现的。
  • 如果类将有子类,则同时分配的任何可变大小的数据必须在对象开始之前,而不是结束之后。在这种情况下,delete这样的对象的唯一安全方法是销毁delete,这样就可以确定分配的正确起始地址。
  • 如果一个类只有几个子类,它可以通过这种方式为析构函数实现自己的动态调度,而不需要使用vtable。这会稍微快一点,并导致较小的班级规模。
 类似资料:
  • 两者的区别是什么 和 例如: 我用这个或那个真的重要吗?

  • 我正在构建一个基于railsguide的rails应用程序 它在erb中调用的语法是... 控制器定义 与在application.html.erb中使用“application”相关联的错误

  • 使用C++20的时,我注意到似乎不能满足概念。根据的定义,在C++20中应该实现以下功能: 这个需求应该实现与的对称比较--根据我的理解,这足以满足。 奇怪的是,这个问题似乎在所有主要编译器上都是一致的。以下代码将从Clang、GCC和msvc中拒绝: 联机尝试 但是,接受与相同的断言: 联机尝试 除非我误会了什么,这似乎是个窃听器。我的问题是,这是三个编译器实现中的一个巧合的bug,还是C++2

  • 问题内容: 当前正在从事一个项目,在该项目中,当我们不从被破坏的示波器中清除广播订阅时,会发现大量内存泄漏。以下代码已解决此问题: 这种做法也应该用于手表吗? 下面的代码示例: 问题答案: 不,您不需要删除,因为一旦销毁范围,它们将被有效删除。 从角的源代码(v1.2.21),的方法: 因此,将清空该数组(并且将范围从范围层次结构中删除)。 无论如何,从阵列中删除都是注销功能所要做的: 因此,取消

  • 销毁 Destroy 在不需要使用iScoll的时候调用iScroll实例的公共方法destroy()可以释放一些内存。 myScroll.destroy(); myScroll = null;

  • 问题内容: 当我使用session_destroy()时,出现“会话对象销毁失败”的消息。 是什么导致此错误? 问题答案: 错误: 警告:session_destroy():会话对象销毁失败 这相当琐碎,没有会话 已启动, 对象已提交,因此您无法销毁它。 该运营商并不总是有效的,例如用错误报告功能。 编辑: 1)导致此错误的原因是什么? 此错误通常是由于PHP尝试删除会话文件而导致的,但找不到它。