C++ 11编译器生成的函数

P0W*_*P0W 8 c++ c++11

说一堂课

class Piece {} ;

如果我是对的,应该相当于:

class Piece {
   //C++ 03
    Piece ();                          //default constructor
    Piece( const Piece&);              //copy constructor
    Piece& operator=(const Piece&);    //copy assignment operator
    ~Piece();                          //destructor

    //Since C++ 11
    Piece(Piece&&);                   //move constructor
    Piece& operator=(Piece&&);        //move assignment operator
};
Run Code Online (Sandbox Code Playgroud)

那么我能说些什么呢?

一个)

class Pawn{
    ~Pawn() {}// Only destructor
};
Run Code Online (Sandbox Code Playgroud)

b)

class Bishop{
    Bishop(Bishop&& ) {}// Only move constructor
};
Run Code Online (Sandbox Code Playgroud)

C)

class Knight{
    Knight(Knight&&, int =0) {} // move constructor, when no second arg present
};
Run Code Online (Sandbox Code Playgroud)

d)

class Rook {
    Rook(const Rook& ) {}// Only copy constructor
};
Run Code Online (Sandbox Code Playgroud)

E)

class King{
        King& operator=(const King&) = delete;
    };
Run Code Online (Sandbox Code Playgroud)

我的理解编译器将生成:

  • a)默认构造函数,复制构造函数,复制赋值运算符,(移动构造函数/赋值运算符?)
  • b)析构函数
  • c)析构函数
  • d)复制赋值运算符和析构函数(移动构造函数/赋值运算符?)
  • e)默认构造函数,复制构造函数,析构函数,(移动构造函数/赋值运算符?)

我在这里纠正或遗漏了什么吗?

基本上是否C++11有任何新的规则来生成函数,当用户不提供时?

dyp*_*dyp 7

我将在这里省略一些不相关的要点,例如关于unions,基类,大括号或等于初始化器等.如果你的类有任何成员,基类,......那么答案就会有所不同.例如,如果您有const成员,则隐式声明的赋值运算符将被定义为已删除.

默认构造函数

[class.ctor]/5

类的默认构造函数是类X的构造函数X,可以在没有参数的情况下调用.如果类没有用户声明的构造X函数,则不会将没有参数的构造函数隐式声明为默认值.隐式声明的默认构造函数是inline public其类的成员.X如果[...这里有许多不相关的点],则默认的类默认构造函数被定义为已删除.

因此,在a)和e)[没有任何用户声明的ctor]的情况下,默认ctor被声明为默认值.

默认析构函数

[class.dtor]

4如果类没有用户声明的析构函数,则析构函数被隐式声明为默认值.隐式声明的析构函数是inline public其类的成员.

5 X如果[这里有很多不相关的点] ,一个类的默认析构函数被定义为删除

因此,在所有情况下,除了a)[使用用户声明的dtor]之外,如果使用odr,则隐式声明默认dtor并隐式定义.


根据[class.copy]/2 + 3,copy-ctor和move-ctor可能有其他参数,如果它们有默认参数.

拷贝构造函数

如果没有用户定义的copy-ctor(ctor模板永远不是copy-ctor),则会隐式声明copy-ctor.[class.copy]/7

如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除; 否则,它被定义为默认.如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况.

也就是说,在所有情况下,除了d)[使用用户声明的copy-ctor],都会隐式声明copy-ctor.在情况b)和c)[使用用户提供的移动ctor]中,复制者被定义为已删除.对于a)[用户声明的dtor]和e)[用户声明的复制赋值op],它可以被定义为默认值,但不推荐使用.

移动构造函数

在这些案件[class.copy]/9中甚至不会宣布移动者

  • X 没有用户声明的复制构造函数,
  • X 没有用户声明的复制赋值运算符,
  • X 没有用户声明的移动赋值运算符,
  • X 没有用户声明的析构函数,和
  • 移动构造函数不会被隐式定义为已删除.

在某些情况下,它会被定义为已删除,但它们不适用于此处.

因此,在任何情况下都不会声明移动者.


复制赋值运算符

在[class.copy]/18中:

如果类定义未显式声明复制赋值运算符,则会隐式声明一个.如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符被定义为已删除; 否则,它被定义为默认.如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用后一种情况.

在某些情况下,它被定义为已删除,请参阅[class.copy]/23,但它们不适用于此处.

复制赋值操作在所有情况下都被声明,但e)[用户声明的复制赋值操作].它在b)和c)中被定义为删除[均为:用户声明的移动ctor]; 它可以在a)[用户声明的dtor]和d)[用户声明的copy-ctor]中定义为默认值.请注意与copy-ctor平行.

移动赋值运算符

与move-ctor类似,如果[class.copy]/20,则甚至不会声明move-assignment op:

  • X 没有用户声明的复制构造函数,
  • X 没有用户声明的移动构造函数,
  • X 没有用户声明的复制赋值运算符,
  • X 没有用户声明的析构函数,和
  • 移动赋值运算符不会被隐式定义为已删除.

在某些情况下,它被定义为已删除,请参阅[class.copy]/23(与copy-ctor相同的段落),但它们不适用于此处.

move-assignment-op被隐式声明,并且在任何情况下被定义为默认值.