【问题标题】:Special member functions in C++0xC++0x 中的特殊成员函数
【发布时间】:2011-03-17 21:12:05
【问题描述】:

关于 special member functions 的 Wikipedia 文章不包含对移动构造函数和移动赋值运算符的任何引用。

我想更新条目,但我不确定 0x 标准是怎么说的。

关于这两个函数的规则是什么?它们是由编译器自动生成的吗?如果是,什么时候生成?


编辑:我已经更新了维基百科页面,如果有人喜欢它,请通过编辑它来帮助社区(如果需要)。

【问题讨论】:

  • 您应该尝试找到最新版本的草稿。 AFAIK,它们不会自动生成,但(希望)可以请求默认版本(X(X&&) = default;

标签: c++ constructor c++11 assignment-operator move-semantics


【解决方案1】:

请记住,C++0x 还不是很标准,这可能会发生变化。从FCD(PDF 链接)来看,移动构造函数和移动赋值运算符确实可以显式默认,甚至隐式默认。*****


我只是引用(大量删节)一些可能有用的东西:

关于显式默认函数,§8.4.2/1-2:

一个显式默认的函数应该

  • 是一个特殊的成员函数,
  • 声明的函数类型与隐式声明的函数类型相同,
  • 没有默认参数,并且
  • 没有异常规范。

如果它在第一个声明中明确默认,

  • 它应该是公开的,
  • 不得明确,
  • 它不能是虚拟的,
  • 隐式认为它具有与隐式声明 (15.4) 相同的异常规范,并且
  • 在复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符的情况下,它应具有与隐式声明的参数类型相同的参数类型。

关于特殊成员函数,§12/1:

默认构造函数 (12.1)、复制构造函数和复制赋值运算符 (12.8)、移动构造函数和移动赋值运算符 (12.8) 和析构函数 (12.4) 是特殊的成员函数。 [注意:当程序没有显式声明它们时,实现会为某些类类型隐式声明这些成员函数。如果使用它们,实现将隐式定义它们。见 12.1、12.4 和 12.8。 ——尾注]

关于隐式声明的函数,§12.8/8-11:

如果类定义没有显式声明复制构造函数并且没有用户声明的移动构造函数,则复制构造函数被隐式声明为默认值 (8.4)。

类 X 的隐式声明的复制构造函数的格式为 X::X(const X&) if

  • X 的每个直接或虚拟基类 B 都有一个复制构造函数,其第一个参数的类型为 const B&const volatile B&,并且
  • 对于 X 的所有属于类类型 M(或其数组)的非静态数据成员,每个此类类型都有一个复制构造函数,其第一个参数的类型为 const M&const volatile M&。李>

否则,隐式声明的复制构造函数将具有X::X(X&) 的形式。

如果类定义没有显式声明一个移动构造函数,当且仅当

  • X 没有用户声明的复制构造函数并且
  • 移动构造函数不会被隐式定义为已删除。

[ 注意:当移动构造函数没有被隐式声明或显式提供时,否则会调用移动构造函数的表达式可能会调用复制构造函数。 ——尾注]

X 类的隐式声明的移动构造函数的格式为X::X(X&&)

关于隐式删除的默认函数,§12.8/12:

隐式声明的复制/移动构造函数是其类的内联公共成员。如果 X 具有以下属性,则类 X 的默认复制/移动构造函数被定义为已删除 (8.4.3):

  • 具有非平凡对应构造函数的变体成员,并且 X 是类联合类,
  • 类类型 M(或其数组)的非静态数据成员无法复制/移动,因为应用于 M 的相应构造函数的重载决议 (13.3) 会导致歧义或函数被删除或无法访问来自默认构造函数,或
  • 无法复制/移动的直接或虚拟基类 B,因为应用于 B 的相应构造函数的重载决议 (13.3) 会导致歧义或从默认构造函数中删除或无法访问的函数,或者李>
  • 对于移动构造函数,非静态数据成员或直接或虚拟基类,其类型没有移动构造函数且不可轻易复制。

§12.8/13-18 定义了函数在隐式生成时应如何工作。

§12.8/19 然后做与 §12.8/8 相同的事情,除了复制赋值和移动赋值运算符。它们非常相似,不值得在这里引用。

要获得更完整的图片,您需要完整阅读这些部分,但这是大意。我很高兴我们得到了隐式移动语义。


*但是就像默认的复制函数一样,它们可能并不总是有正确的行为!三巨头应该成为五巨头。 (例如,当我们需要深度复制某些东西时,就会实现三巨头。我们还需要确保我们执行“深度移动”,即源数据被清空/重置。这不是 em> 隐式完成。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2012-10-14
    • 2015-03-04
    • 1970-01-01
    • 2016-06-09
    • 2012-01-27
    相关资源
    最近更新 更多