【问题标题】:How are dynamic objects of a type with a deleted destructor constructed?如何构造具有已删除析构函数的类型的动态对象?
【发布时间】:2016-06-14 07:36:04
【问题描述】:

假设我有一些看起来像这样的东西:

struct foo {
    ~foo() = delete;
}

假设我后来动态分配了一个foo类型的对象:

foo *f = new foo;

这很好;我假设合成的默认构造函数用于构造f 表示的对象,但是:

foo f2;

给我一​​个错误:

尝试使用已删除的函数

那么如果foo 的默认构造函数被隐式删除,f 表示的对象是如何构造的呢?

此外,假设foo 拥有私有成员size_t n。对于动态分配的foo,例如f 表示的n 的值是多少?

【问题讨论】:

  • 构造函数没有被删除,只有析构函数被删除(并且需要销毁f2)。出于同样的原因,你也不能说delete f。
  • @molbdnilo 好的,但是为什么在构造函数没有被删除的情况下我不能构造一个非动态的foo?
  • @Badbit 因为它们在超出范围时会被破坏,所以它们需要一个析构函数。
  • 因为构造函数和析构函数在非动态内存分配上被隐式调用。你应该两者都有。
  • @Badbit 我不相信你已经删除了唯一的构造函数。您已经删除了析构函数,并且由于您没有在类中声明任何其他构造函数,因此 C++ 将免费为您提供默认构造函数。

标签: c++ c++11 destructor c++14


【解决方案1】:

当你写作时

foo f;

编译器需要能够在最初创建 f 时构造它。由于该变量具有自动存储持续时间(“在堆栈上”的花哨 C++ 术语),编译器也负责生成代码以清理它。这需要访问析构函数,但由于您已将其删除,因此会出现错误。

当你写作时

foo* f = new foo;

您正在堆栈上创建指向 foo 对象的指针,编译器可以在不访问 foo 析构函数的情况下销毁指针本身。另一方面,使用 new foo 创建的对象具有动态存储期限,这意味着您承诺手动销毁它。因此,编译器不需要访问析构函数,因此创建步骤很好。也就是说,如果你再写

delete f;

您应该得到一个错误,因为该操作确实需要析构函数。

编辑:从您的后续行动来看,我的感觉是您想知道为什么即使删除了析构函数,仍然会生成默认构造函数。我有一份 C++14 规范草案,在 §12.1.4 中,它说如下:

类 X 的默认构造函数是类 X 的构造函数,可以在没有参数的情况下调用。如果 类 X 没有用户声明的构造函数,隐式声明了没有参数的构造函数 默认(8.4)。隐式声明的默认构造函数是其类的内联公共成员。一种 类 X 的默认默认构造函数在以下情况下定义为已删除:

— X 是一个类联合类,它有一个变体成员和一个非平凡的默认构造函数,

——任何没有大括号或等号初始化器的非静态数据成员都是引用类型,

——任何非变体非静态数据成员的 const 限定类型(或其数组),没有大括号或 - equal-initializer 没有用户提供的默认构造函数,

— X 是一个联合,它的所有变体成员都是 const 限定类型(或其数组),

— X 是一个非联合类,并且任何匿名联合成员的所有成员都是 const 限定类型 (或其数组),

——任何直接或虚拟基类,或没有大括号或等号初始化器的非静态数据成员,具有类 类型 M(或其数组)并且 M 没有默认构造函数或应用的重载决议(13.3) to M 的默认构造函数会导致歧义或导致函数被删除或无法访问 默认的默认构造函数,或

— 任何直接或虚拟基类或非静态数据成员都具有带有已删除析构函数的类型 或无法从默认的默认构造函数中访问。

换句话说,析构函数的删除对默认构造函数的自动生成没有影响。

【讨论】:

  • 感谢您的回答,非常感谢!我相信我的困惑源于我书中的宗教观点,即当析构函数被删除或无法访问时,构造函数被删除。既然我是个白痴,正如所证明的那样,当涉及到隐式删除的成员时,有人会善意地引用标准或其他东西吗?
  • 精彩的编辑,我不敢相信 C++ Primer 骗了我,或者我只是没有注意......
  • @Alt-RockNinjaCowgirl C++ Primer 没有骗你。我认为您正在谈论这本书中的这一行“如果类的成员具有已删除或不可访问的析构函数,则合成的默认构造函数被定义为已删除”。请注意我认为您可能错过的成员一词。
猜你喜欢
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
  • 2020-10-03
  • 2013-05-21
  • 2019-10-08
  • 2012-12-26
相关资源
最近更新 更多