Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are move constructors/assignment operators generated for derived classes

Tags:

c++

c++11

If class X is derived from class Y and class Y has any of:

  • A user-declared copy constructor,
  • A user-declared copy assignment operator,
  • A user-declared destructor
  • A user-declared move constructor,
  • A user-declared move assignment operator,

Will a move constructor and move assignment operator be implicitly defaulted for class X providing it declares none of the above?

e.g.

struct Y
{
     virtual ~Y() {}

     // .... stuff

};

struct X : public Y
{
   // ... stuff but no destructor, 
   //               no copy/move assignment operator 
   //               no copy/move constructor

   // will X have a default move constructor / assignment operator?
};

I am currently using gcc, but I am mainly interested in what the correct behaviour should be (as opposed to whether or not a particular compiler is standards compliant)..

like image 830
mark Avatar asked May 22 '12 10:05

mark


People also ask

Are move constructor automatically generated?

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.

Which is true about move operations move constructor move assignment operator?

The move assignment operator is different than a move constructor because a move assignment operator is called on an existing object, while a move constructor is called on an object created by the operation. Thereafter, the other object's data is no longer valid.

What does the move constructor do?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class, MemoryBlock , which manages a memory buffer.

What does std :: move () do?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.


2 Answers

As far as the derived class is concerned, the fact that an attribute or a base class has user-defined or implicit special functions does not matter. All that matter is their presence.

Compliant C++11 compilers should automatically provide the move constructors and assignment operators for the struct and class, if possible (which is clearly defined in the Standard), even though only classes with dynamically allocated buffers will really benefit from it (moving an int is just copying it).

Therefore, if your class embeds a std::string or a std::unique_ptr (for example), then its move constructor will call the embedded string or unique_ptr move constructor and it will be efficient... for free.

Simply changing the compilation mode should thus slightly improve performance.

like image 87
Matthieu M. Avatar answered Sep 28 '22 02:09

Matthieu M.


Yes, they are, in §12.8.9:

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

  • 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.

and §12.8.10

The implicitly-declared move constructor for class X will have the form

X::X(X&&)

Similarly, for move assignment operators in 12.8.20:

If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if

  • 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.

Base classes don't come into it directly.

like image 23
juanchopanza Avatar answered Sep 28 '22 00:09

juanchopanza