说一堂课
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)
我的理解编译器将生成:
我在这里纠正或遗漏了什么吗?
基本上是否C++11
有任何新的规则来生成函数,当用户不提供时?
我将在这里省略一些不相关的要点,例如关于union
s,基类,大括号或等于初始化器等.如果你的类有任何成员,基类,......那么答案就会有所不同.例如,如果您有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被隐式声明,并且在任何情况下都被定义为默认值.