代码之家  ›  专栏  ›  技术社区  ›  Motti

C++ 0x中的特殊成员函数

  •  3
  • Motti  · 技术社区  · 15 年前

    维基百科关于 special member functions

    关于这两个功能有什么规则?它们是否由编译器自动生成?如果是,何时生成?


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

    1 回复  |  直到 15 年前
        1
  •  3
  •   Community Mohan Dere    5 年前

    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:

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

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

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

    如果类定义没有显式声明move构造函数,则当且仅当

    • 移动构造函数不会隐式定义为已删除。

    类X隐式声明的move构造函数的形式为 X::X(X&&) .

    隐式声明的复制/移动构造函数是其类的内联公共成员。类X的默认复制/移动构造函数定义为deleted(8.4.3),如果X具有:

    • 一个变量成员有一个非平凡的对应构造函数,X是一个类并集,
    • 类类型M(或其数组)的非静态数据成员,由于应用于Ms对应构造函数的重载解析(13.3)导致歧义或从默认构造函数中删除或无法访问的函数而无法复制/移动,或
    • 对于move构造函数,是一种非静态数据成员或直接或虚拟基类,其类型没有move构造函数且不可复制。

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

    要获得更完整的图片,您可能希望完整地阅读这些部分,但这只是总体思路。我很高兴我们得到了隐含的移动语义。


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