自动生成默认/复制/移动向量和复制/移动赋值运算符的条件?

发布于 2024-10-16 17:46:25 字数 99 浏览 4 评论 0原文

我想刷新我对编译器通常自动生成默认构造函数、复制构造函数和赋值运算符的条件的记忆。

我记得有一些规则,但我不记得了,而且也无法在网上找到信誉良好的资源。有人可以帮忙吗?

I want to refresh my memory on the conditions under which a compiler typically auto generates a default constructor, copy constructor and assignment operator.

I recollect there were some rules, but I don't remember, and also can't find a reputable resource online. Can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

残龙傲雪 2024-10-23 17:46:25

在下文中,“自动生成”的意思是“隐式声明为默认,但未定义为删除”。在某些情况下,声明了特殊成员函数,但定义为已删除。

  • 如果没有用户声明的构造函数,则自动生成默认构造函数(第 12.1/5 节)。
  • 如果没有用户声明的移动构造函数或移动赋值运算符,则自动生成复制构造函数(因为 C++03 中没有移动构造函数或移动赋值运算符,这在 C++03 中简化为“始终”)( §12.8/8)。
  • 如果没有用户声明的移动构造函数或移动赋值运算符,则自动生成复制赋值运算符(第 12.8/19 节)。
  • 如果没有用户声明的析构函数,析构函数会自动生成(第 12.4/4 节)。

仅 C++11 及更高版本:

  • 如果没有用户声明的复制构造函数、复制赋值运算符或析构函数,并且生成的移动构造函数有效,则自动生成移动构造函数 (§12.8/10)。
  • 如果没有用户声明的复制构造函数、复制赋值运算符或析构函数,并且生成的移动赋值运算符有效(例如,如果不需要分配常量成员),则自动生成移动赋值运算符(§12.8/ 21)。

In the following, "auto-generated" means "implicitly declared as defaulted, but not defined as deleted". There are situations where the special member functions are declared, but defined as deleted.

  • The default constructor is auto-generated if there is no user-declared constructor (§12.1/5).
  • The copy constructor is auto-generated if there is no user-declared move constructor or move assignment operator (because there are no move constructors or move assignment operators in C++03, this simplifies to "always" in C++03) (§12.8/8).
  • The copy assignment operator is auto-generated if there is no user-declared move constructor or move assignment operator (§12.8/19).
  • The destructor is auto-generated if there is no user-declared destructor (§12.4/4).

C++11 and later only:

  • The move constructor is auto-generated if there is no user-declared copy constructor, copy assignment operator or destructor, and if the generated move constructor is valid (§12.8/10).
  • The move assignment operator is auto-generated if there is no user-declared copy constructor, copy assignment operator or destructor, and if the generated move assignment operator is valid (e.g. if it wouldn't need to assign constant members) (§12.8/21).
合约呢 2024-10-23 17:46:25

我发现下图非常有用。

C++ 规则自动构造函数和赋值运算符
来自粘性位 - 成为零英雄的规则

I've found the diagram below very useful.

C++ rules for automatic constructors and assignment operators
from Sticky Bits - Becoming a Rule of Zero Hero

许一世地老天荒 2024-10-23 17:46:25

C++17 N4659 标准草案

如需快速交叉标准参考,请查看以下 cppreference 条目的“隐式声明”部分:

当然可以从标准中获得相同的信息。例如 C++17 N4659 标准草案

15.8.1 “复制/移动构造函数”表示复制构造函数:

6 如果类定义没有显式声明复制构造函数,则隐式声明非显式复制构造函数。
如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的副本
构造函数被定义为已删除;否则,它被定义为默认(11.4)。后一种情况将被弃用,如果
该类具有用户声明的复制赋值运算符或用户声明的析构函数。

对于移动构造函数:

8 如果类 X 的定义没有显式声明移动构造函数,则非显式的移动构造函数将被隐式声明
声明为默认当且仅当

  • (8.1)
    — X 没有用户声明的复制构造函数,

  • (8.2)
    — X 没有用户声明的复制赋值运算符,

  • (8.3)
    — X 没有用户声明的移动赋值运算符,并且

  • (8.4)
    — X 没有用户声明的析构函数。

15.8.2“复制/移动赋值运算符”对于复制赋值表示:

2 如果类定义没有显式声明复制赋值运算符,则隐式声明一个。
如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的
复制赋值运算符定义为删除;否则,它被定义为默认(11.4)。后者
如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用 case。

对于移动分配:

4 如果类 X 的定义没有显式声明移动赋值运算符,则将隐式声明一个移动赋值运算符
声明为默认当且仅当

  • (4.1) — X 没有用户声明的复制构造函数,
  • (4.2) — X 没有用户声明的移动构造函数,
  • (4.3) — X 没有用户声明的复制赋值运算符,并且
  • (4.4) — X 没有用户声明的析构函数。

15.4“析构函数”对于析构函数是这样说的:

4 如果类没有用户声明的析构函数,则析构函数将隐式声明为默认析构函数 (11.4)。一个
隐式声明的析构函数是其类的内联公共成员。

C++17 N4659 standard draft

For a quick cross standard reference, have a look at the "Implicitly-declared" sections of the following cppreference entries:

The same information can of course be obtained from the standard. E.g. on C++17 N4659 standard draft:

15.8.1 "Copy/move constructors" says for for copy constructor:

6 If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
constructor is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter case is deprecated if
the class has a user-declared copy assignment operator or a user-declared destructor.

and for move constructor:

8 If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly
declared as defaulted if and only if

  • (8.1)
    — X does not have a user-declared copy constructor,

  • (8.2)
    — X does not have a user-declared copy assignment operator,

  • (8.3)
    — X does not have a user-declared move assignment operator, and

  • (8.4)
    — X does not have a user-declared destructor.

15.8.2 "Copy/move assignment operator" says for copy assignment:

2 If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared
copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter
case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.

and for move assignment:

4 If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly
declared as defaulted if and only if

  • (4.1) — X does not have a user-declared copy constructor,
  • (4.2) — X does not have a user-declared move constructor,
  • (4.3) — X does not have a user-declared copy assignment operator, and
  • (4.4) — X does not have a user-declared destructor.

15.4 "Destructors" says it for destructors:

4 If a class has no user-declared destructor, a destructor is implicitly declared as defaulted (11.4). An
implicitly-declared destructor is an inline public member of its class.

橘和柠 2024-10-23 17:46:25

Howard Hinnant 的下图很好地总结了所有规则。
红细胞是已弃用的行为(请参阅 [depr.impldec]),并且可能会更改在某个时刻删除

C++ 规则对于自动构造函数和赋值运算符

来源:Howard Hinnant - 我如何声明我的class 以及原因

The following graphic by Howard Hinnant sums all the rules up nicely.
Red cells are deprecated behavior (see [depr.impldec]) and may be changed to deleted at some point.

C++ rules for automatic constructors and assignment operators

Source: Howard Hinnant - How I Declare My class And Why

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文