假设我有一些看起来像这样的东西:
struct foo {
~foo() = delete;
}
假设我后来动态分配类型的对象foo
:
foo *f = new foo;
这可以; 我假设使用合成的默认构造函数构造由表示的对象f
,但是:
foo f2;
给我一个错误:
尝试使用已删除的功能
那么,f
如果foo
隐式删除的默认构造函数,该构造的对象如何表示呢?
而且,假设foo
有私人会员size_t n
。n
动态分配的的值是多少(foo
例如用表示的值)f
?
当你写
foo f;
最初创建时,编译器需要能够构造f。由于该变量具有自动存储持续时间(“栈上”的奇特的C ++术语),因此编译器还负责生成代码以对其进行清理。这需要访问析构函数,但是由于已将其删除,因此会出现错误。
当你写
foo* f = new foo;
您正在堆栈上创建一个指向foo对象的指针,编译器可以破坏该指针本身而无需访问foo析构函数。另一方面,使用新foo创建的对象具有动态存储持续时间,这意味着您承诺手动销毁它。因此,编译器不需要访问析构函数,因此创建步骤很好。也就是说,如果你再写
delete f;
您应该得到一个错误,因为该操作确实需要析构函数。
编辑:从您的后续,我的感觉是您想知道为什么即使删除了析构函数,仍会生成默认构造函数。我有一份C ++ 14规范的草案,在§12.1.4中有以下内容:
X类的默认构造函数是X类的构造函数,无需参数即可调用它。如果没有用户声明的类X构造函数,则将不带参数的构造函数隐式声明为默认值(8.4)。隐式声明的默认构造函数是其类的内联公共成员。如果满足以下条件,则将X类的默认默认构造函数定义为已删除:
— X是类联合的类,其变体成员具有非平凡的默认构造函数,
—任何没有大括号或等于初始化器的非静态数据成员都是引用类型,
—任何不带大括号或相等初始化器的const限定类型(或其数组)的非变量非静态数据成员,都没有用户提供的默认构造函数,
— X是一个联合,并且其所有变体成员都是const限定类型(或其数组),
— X是非联盟类,任何匿名联合成员的所有成员均为const限定类型(或其数组),
—任何直接或虚拟基类,或者没有大括号或相等初始化器的非静态数据成员,具有类类型M(或其数组),并且M没有应用于M的默认构造函数或重载分辨率(13.3)默认构造函数导致模棱两可,或者导致从默认默认构造函数中删除或无法访问的函数,或者
—任何直接或虚拟基类或非静态数据成员都具有带有析构函数的类型,该析构函数已从默认的默认构造函数中删除或无法访问。
换句话说,删除析构函数不会影响默认构造函数的自动生成。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句