【问题标题】:When does the compiler provide definitions for the special members of a class?编译器何时为类的特殊成员提供定义?
【发布时间】:2012-01-27 02:36:13
【问题描述】:

我知道,当我定义一个空类并且根本不提供任何声明时,编译器会为默认和复制构造函数、析构函数和复制赋值运算符提供定义。

这有什么规则?编译器何时提供复制构造函数?移动构造函数和移动赋值运算符呢?

(例如:如果我的类有 int& 这样的引用成员,编译器将不会为任何赋值运算符提供定义。其他什么时候会发生这种情况?)

【问题讨论】:

  • @Mr.TAMER:维基百科很好,但我想有一个完整的 SO 列表,最好是标准引号。 :) 此外,维基百科文章没有说明何时获得移动构造函数以及何时不提供复制 ctor / 赋值操作。
  • 会不会不提供赋值运算符,即使你有引用成员。尝试使用它会生成编译,不是因为它不存在,而是因为它无效。
  • 在不输入标准第 12 章的大量内容的情况下,我们应该如何回答这个问题?这一切都在那里,它是标准中非常明确的一部分。
  • “我知道,当我定义一个空类并且根本不提供任何声明时,编译器将提供默认和复制构造函数、析构函数和复制赋值运算符的定义。”。这是不正确的。它只会提供这些的声明。并且定义仅在需要时使用。
  • @Xeo 不,这些不是形式。如果你有struct A { void operator=(int); operator int(); int &x; }; A a{*new int}, b{*new int};,如果你说a = b;,它会给出一个错误,因为它确实提供了复制分配的声明。如果不是,它不是是一个错误,但它会将b转换为int

标签: c++ constructor c++11 destructor assignment-operator


【解决方案1】:

编辑:在 C++11 中,它比隐式声明或不隐式声明更复杂。它们可以被隐式声明和默认,隐式声明和删除,或未声明。阅读this以区分后者2。以下信息并不完全正确,因为它不区分已声明和已删除与未声明。

以下是正在进行的工作。 (?) 表示我想澄清或量化该声明。

特殊成员函数 §12/1

当用户没有显式声明它们时,实现会为某些类类型隐式声明这些成员函数:

  • 默认构造函数
  • 复制构造函数
  • 复制赋值运算符
  • 移动构造函数
  • 移动赋值运算符
  • 析构函数

如果类型有一个特殊的成员函数,则不会隐式声明...


默认构造函数§12.1/5


复制构造函数§12.8/8, §12.8/12

  • 用户声明的移动构造函数
  • 用户声明的移动赋值运算符
  • 右值引用类型的非静态数据成员
  • 具有非平凡复制构造函数的变体成员并且是类联合类 (?)
  • 无法复制的类型(或其数组)的非静态数据成员
  • 没有可访问复制构造函数的直接或虚拟基类

*如果类具有用户声明的复制赋值运算符或用户声明的析构函数 (?),则不推荐使用此类隐式声明


复制赋值运算符§12.8/19, §12.8/24

  • 用户声明的移动构造函数
  • 用户声明的移动赋值运算符
  • 具有非平凡复制赋值运算符的变体成员,是类联合类 (?)
  • const 非类类型(或其数组)的非静态数据成员
  • 引用类型的非静态数据成员
  • 具有不可访问的复制赋值运算符的非静态数据成员
  • 具有不可访问的复制赋值运算符的直接或虚拟基类

*如果类具有用户声明的复制构造函数或用户声明的析构函数 (?),则不推荐使用此类隐式声明


移动构造函数§12.8/10, §12.8/12

  • 用户声明的复制构造函数
  • 用户声明的复制赋值运算符
  • 用户声明的移动赋值运算符
  • 用户声明的析构函数
  • 移动构造函数不会被隐式定义为已删除 (?)
  • variant 成员具有非平凡的移动构造函数并且是类联合类 (?)
  • 不能移动的类型(或其数组)的非静态数据成员
  • 非静态数据成员或直接或虚拟基类,其类型没有移动构造函数且不可轻易复制
  • 没有可访问的移动构造函数的直接或虚拟基类

移动赋值运算符§12.8/21, §12.8/24

  • 用户声明的复制构造函数
  • 用户声明的移动构造函数
  • 用户声明的复制赋值运算符
  • 用户声明的析构函数
  • 移动赋值运算符不会被隐式定义为已删除 (?)
  • 具有非平凡移动赋值运算符的变体成员,是类联合类 (?)
  • const 非类类型(或其数组)的非静态数据成员
  • 引用类型的非静态数据成员
  • 具有不可访问的移动赋值运算符且不可轻易复制的非静态数据成员
  • 具有不可访问的移动赋值运算符且不可轻易复制的直接或虚拟基类

析构函数§12.4/4

【讨论】:

    猜你喜欢
    • 2020-07-05
    • 2021-03-08
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 2011-12-11
    • 2022-11-25
    • 2013-01-24
    • 1970-01-01
    相关资源
    最近更新 更多