如何构造具有删除的析构函数的动态对象?

Alt-Rock Ninja女牛仔

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

struct foo {
    ~foo() = delete;
}

假设我后来动态分配类型的对象foo

foo *f = new foo;

这可以; 我假设使用合成的默认构造函数构造由表示的对象f,但是:

foo f2;

给我一个错误:

尝试使用已删除的功能

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

而且,假设foo有私人会员size_t nn动态分配的的值是多少(foo例如用表示的值)f

templatetypedef

当你写

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

具有私有构造函数和析构函数的类对象的向量?

是否可以实例化具有删除的构造函数和析构函数的非聚合类?

使用已删除或非用户提供的私有析构函数构造(但不破坏)类的对象

对具有动态分配内存和析构函数的类对象的引用

使用私有析构函数删除动态分配的对象

为什么允许我声明具有删除的析构函数的对象?

对象的构造函数和析构函数

如何通过使用自定义构造函数而不调用析构函数来创建具有初始大小的向量?

删除包含动态数组作为数据成员的对象时的C ++析构函数用法

如何检测构造函数是否为带有抛出析构函数的异常

具有非平凡constexpr析构函数的consteval函数返回对象

C ++构造函数/析构函数调用&在动态创建的数据上调用“ new”会删除旧数据吗?

构造函数/析构函数方法是否有总括术语?

此类的构造函数/析构函数有问题吗?

具有受保护的析构函数的类数组的动态分配

使用析构函数是为了删除动态分配的数组还是所有数组?

C#,删除带有子线程的对象时,GC没有调用析构函数

构造函数和析构函数如何工作?

为类编写复制构造函数会在删除析构函数中的对象时导致意外崩溃

如果类具有析构函数/删除[],则成员运算符new []的参数“ size”增加

具有虚拟和非虚拟析构函数的删除运算符的不同行为

父类析构函数会删除具有外部启动元素的子类吗?

析构函数删除main中声明的动态数组

如何在动态数组中的某些对象上调用析构函数

具有unique_ptr成员和自定义析构函数的对象的向量

为什么带有用户声明的析构函数的类具有隐式默认构造函数?

通过指向基的指针删除对象,而没有虚拟析构函数

删除另一个类中带有受保护析构函数的对象

具有专门析构函数的“析构函数已定义”