C ++ 11编译器生成的函数 [英] C++11 compiler generated functions

查看:152
本文介绍了C ++ 11编译器生成的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说班



class Piece {};


$ b b

如果我是正确的,应该等效于:

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

//因为C ++ 11
Piece(&&;); // move constructor
Piece& operator =(Piece&&;); // move assignment operator
};

那么我能说些什么呢?



a)

  class Pawn {
〜Pawn(){} //只有析构函数
} ;

b)

 code> class Bishop {
Bishop(Bishop&){} //只移动构造函数
};

c)

  class Knight {
Knight(Knight&& amp; int = 0){} //没有第二个arg时移动构造函数
};

d)

 code> class Rook {
Rook(const Rook&){} //只复制构造函数
};

e)

  class King {
King& operator =(const King&)= delete;
};

我的理解编译器会生成:




  • a)默认构造函数,复制构造函数,复制赋值运算符(move constructor / assignment operator?)

  • b)析构函数

  • c)析构函数

  • d)复制赋值运算符和析构函数(移动构造函数/赋值运算符)

  • <复制构造函数,析构函数(移动构造函数/赋值运算符?)



$ b

基本上是 C ++ 11 在没有用户提供的时候有任何新的生成函数的规则?

解决方案

我会在这里省略一些不相关的地方,例如: about union s,base classes, brace-or-equal-initializers如果你的类有任何成员,基类...答案会有所不同。例如,如果你有一个 const 成员,隐式声明的赋值操作符将被定义为已删除。



构造函数



[class.ctor] / 5


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


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



default destructor



[class.dtor]


4如果类没有用户-declared析构函数,析构函数被隐式声明为default。一个隐式声明的析构函数是它的类的一个 inline public 成员。



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


所以在所有情况下,但是a)[使用用户声明的dtor],默认dtor是隐式声明和隐式定义如果odr使用。






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



复制构造函数



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


如果类定义声明一个移动构造函数或移动赋值运算符,则隐式声明的拷贝构造函数定义为删除;否则,它被定义为默认值。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,后一种情况将被弃用。


所有情况,但d)[用用户声明的copy-ctor],隐式声明copy-ctor。在情况b)和c)中[使用用户提供的move ctor],copy-ctor被定义为已删除。对于a)[用户声明的dtor]和e)[用户声明的复制赋值操作],它可以定义为默认值,但是已被弃用。



构造函数



在这些情况下甚至不会声明move-ctor [class.copy] / 9



  • X 没有用户声明的复制构造函数,

  • X 没有用户声明的副本赋值运算符,

  • X 没有用户声明的移动赋值运算符,

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




因此,move-ctor是


$ b

复制赋值运算符

在[class.copy] / 18中:


如果类定义没有显式声明一个复制赋值运算符,隐含。如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制赋值操作符被定义为删除;否则,它被定义为默认值。如果类具有用户声明的复制构造函数或用户声明的析构函数,后一种情况将被弃用。




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



移动赋值运算符



如果[class.copy] / 20:



  • X 没有用户声明的复制构造函数,

  • X 用户声明的移动构造函数

  • X 没有用户声明的复制赋值运算符,

  • X 没有用户声明的析构函数,

  • 移动赋值操作符不会被隐式定义为已删除


在某些情况下定义为已删除,请参阅[class.copy] / 23



移动赋值操作是隐式声明的,并定义为中的默认值。无


Say a class

class Piece {} ;

If I'm correct that should be equivalent to :

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
};

So what can I say about these ?

a)

class Pawn{
    ~Pawn() {}// Only destructor
};

b)

class Bishop{
    Bishop(Bishop&& ) {}// Only move constructor
};

c)

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

d)

class Rook {
    Rook(const Rook& ) {}// Only copy constructor
};

e)

class King{
        King& operator=(const King&) = delete;
    };

My per my understanding compiler will generate for :

  • a) Default Constructor, Copy Constructor, Copy Assignment operator , ( move constructor/assignment operator ? )
  • b) Destructor
  • c) Destructor
  • d) Copy Assignment operator and Destructor ( move constructor/assignment operator ? )
  • e) Default Constructor, Copy Constructor, Destructor, ( move constructor/assignment operator ? )

Am I correct or missing something here ?

Basically is C++11 has any new rules for generating functions, when not provided by user ?

解决方案

I'll leave out some irrelevant points here, e.g. about unions, base classes, brace-or-equal-initializers etc. If your classes have any members, base classes, ... then the answer will differ. For example, if you have a const member, an implicitly declared assignment operator would be defined as deleted.

default constructor

[class.ctor]/5

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted. An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if [... lots of points irrelevant here].

So in cases a) and e) [without any user-declared ctor], a default ctor is declared as defaulted.

default destructor

[class.dtor]

4 If a class has no user-declared destructor, a destructor is implicitly declared as defaulted. An implicitly-declared destructor is an inline public member of its class.

5 A defaulted destructor for a class X is defined as deleted if [... lots of points irrelevant here]

So in all cases but a) [with a user-declared dtor], a default dtor is implicitly declared and implicitly defined if odr-used.


As per [class.copy]/2+3, a copy-ctor and move-ctor may have additional parameters, if those have default arguments.

copy-constructor

A copy-ctor is declared implicitly if there's no user-defined copy-ctor (a ctor template is never a copy-ctor). [class.copy]/7

If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted. The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

That is, in all cases but d) [with a user-declared copy-ctor], a copy-ctor is declared implicitly. In cases b) and c) [with a user-provided move ctor], the copy-ctor is defined as deleted. For a) [user-declared dtor] and e) [user-declared copy-assignment op], it may be defined as defaulted, but that's deprecated.

move-constructor

The move-ctor won't even be declared in these cases [class.copy]/9

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator,
  • X does not have a user-declared destructor, and
  • the move constructor would not be implicitly defined as deleted.

There are again quite some cases where it would be defined as deleted, but they don't apply here.

Therefore, the move-ctor is not declared in any of the cases.


copy-assignment operator

In [class.copy]/18:

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted. The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.

It is defined as deleted in some cases, see [class.copy]/23, but they don't apply here.

The copy-assignment op is declared in all cases but e) [user-declared copy-assignment op]. It is defined as deleted in b) and c) [both: user-declared move ctor]; and it may be defined as defaulted in a) [user-declared dtor] and d) [user-declared copy-ctor]. Note the parallel to the copy-ctor.

move-assignment operator

Similar to the move-ctor, the move-assignment op is not even declared if either [class.copy]/20:

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared move constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared destructor, and
  • the move assignment operator would not be implicitly defined as deleted.

It is defined as deleted in some cases, see [class.copy]/23 (same paragraph as for the copy-ctor), but they don't apply here.

A move-assignment-op is declared implicitly and defined as defaulted in none of the cases.

这篇关于C ++ 11编译器生成的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆