具有已删除析构函数的类型的动态对象是如何构造的?
How are dynamic objects of a type with a deleted destructor constructed?
假设我有这样的东西:
struct foo {
~foo() = delete;
}
假设我稍后动态分配类型为 foo
的对象:
foo *f = new foo;
这很好;我假设合成的默认构造函数用于构造由 f
表示的对象,但是:
foo f2;
给我一个错误:
Attempt to use a deleted function
那么如果foo
的默认构造函数被隐式删除,那么f
表示的对象是如何构造的呢?
此外,假设 foo
有私有成员 size_t n
。对于动态分配的 foo
,例如 f
表示的 n
的值是多少?
写的时候
foo f;
编译器需要能够在最初创建 f 时对其进行构造。由于该变量具有自动存储持续时间("on the stack" 的奇特 C++ 术语),编译器也负责生成代码来清理它。这需要访问析构函数,但由于您已删除它,因此会出现错误。
写的时候
foo* f = new foo;
您正在堆栈上创建指向 foo 对象的指针,编译器可以在不访问 foo 析构函数的情况下销毁指针本身。另一方面,用 new foo 创建的对象具有动态存储持续时间,这意味着您承诺手动销毁它。因此,编译器不需要访问析构函数,因此创建步骤没问题。也就是说,如果你再写
delete f;
您应该得到一个错误,因为该操作确实需要析构函数。
编辑:从你的后续行动来看,我的感觉是你想知道为什么即使删除了析构函数,仍然会生成默认构造函数。我有一份 C++14 规范草案,在 §12.1.4 中,它说了以下内容:
A default constructor for a class X is a constructor of class X that can be called without an argument. If
there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared
as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A
defaulted default constructor for class X is defined as deleted if:
— X is a union-like class that has a variant member with a non-trivial default constructor,
— any non-static data member with no brace-or-equal-initializer is of reference type,
— any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-
equal-initializer does not have a user-provided default constructor,
— X is a union and all of its variant members are of const-qualified type (or array thereof),
— X is a non-union class and all members of any anonymous union member are of const-qualified type
(or array thereof),
— any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class
type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied
to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from
the defaulted default constructor, or
— any direct or virtual base class or non-static data member has a type with a destructor that is deleted
or inaccessible from the defaulted default constructor.
换句话说,删除析构函数对默认构造函数的自动生成没有影响。
假设我有这样的东西:
struct foo {
~foo() = delete;
}
假设我稍后动态分配类型为 foo
的对象:
foo *f = new foo;
这很好;我假设合成的默认构造函数用于构造由 f
表示的对象,但是:
foo f2;
给我一个错误:
Attempt to use a deleted function
那么如果foo
的默认构造函数被隐式删除,那么f
表示的对象是如何构造的呢?
此外,假设 foo
有私有成员 size_t n
。对于动态分配的 foo
,例如 f
表示的 n
的值是多少?
写的时候
foo f;
编译器需要能够在最初创建 f 时对其进行构造。由于该变量具有自动存储持续时间("on the stack" 的奇特 C++ 术语),编译器也负责生成代码来清理它。这需要访问析构函数,但由于您已删除它,因此会出现错误。
写的时候
foo* f = new foo;
您正在堆栈上创建指向 foo 对象的指针,编译器可以在不访问 foo 析构函数的情况下销毁指针本身。另一方面,用 new foo 创建的对象具有动态存储持续时间,这意味着您承诺手动销毁它。因此,编译器不需要访问析构函数,因此创建步骤没问题。也就是说,如果你再写
delete f;
您应该得到一个错误,因为该操作确实需要析构函数。
编辑:从你的后续行动来看,我的感觉是你想知道为什么即使删除了析构函数,仍然会生成默认构造函数。我有一份 C++14 规范草案,在 §12.1.4 中,它说了以下内容:
A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if:
— X is a union-like class that has a variant member with a non-trivial default constructor,
— any non-static data member with no brace-or-equal-initializer is of reference type,
— any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or- equal-initializer does not have a user-provided default constructor,
— X is a union and all of its variant members are of const-qualified type (or array thereof),
— X is a non-union class and all members of any anonymous union member are of const-qualified type (or array thereof),
— any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
— any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.
换句话说,删除析构函数对默认构造函数的自动生成没有影响。