Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 compiler generated functions

Tags:

c++

c++11

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 ?

like image 478
P0W Avatar asked Oct 26 '13 12:10

P0W


Video Answer


1 Answers

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.

like image 77
dyp Avatar answered Sep 21 '22 03:09

dyp