首页 > 解决方案 > 为什么要为未删除的对象调用析构函数?

问题描述

struct A
{
    ~A() = delete;
};

int main()
{
    new A{};
}

这无法编译并显示错误消息:

错误:使用已删除的函数 'A::~A()' new A{};

据我了解,我没有破坏该对象,那么它为什么要尝试调用析构函数?

使用 GCC 8.1.0 编译

g++ -std=c++17 -O2

标签: c++language-lawyer

解决方案


这是gcc 错误 57082


让我们从下往上。

[dcl.fct.def.delete]/2

隐式或显式引用已删除函数(而不是声明它)的程序是格式错误的。

显然,我们没有~A()明确提及。我们是否隐含地提到它?[class.dtor]/12

隐式调用析构函数

  • 对于在程序终止([basic.start.term])时具有静态存储持续时间([basic.stc.static])的构造对象,
  • 对于在线程退出时具有线程存储持续时间([basic.stc.thread])的构造对象,
  • 对于在其中创建对象的块退出([stmt.dcl])时具有自动存储持续时间([basic.stc.auto])的构造对象,
  • 对于构造的临时对象,当其生命周期结束时([conv.rval],[class.temporary])。

或在[expr.new]/20中:

如果new 表达式创建了一个类类型的对象数组,则可能会调用析构函数。

我们有这些东西吗?不,这里没有具有自动、静态或线程存储持续时间的对象,也没有构造的临时对象,我们的new 表达式也没有创建数组。这里根本只有一个对象A,我们正在聚合初始化的具有动态存储持续时间的对象。

由于我们既没有显式也没有隐式地引用~A(),所以我们不能违反该规则。因此,gcc 错误。还要注意 gcc 接受new A;and new A();,就本规则而言,它们具有相同的含义。


推荐阅读