Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When will adding a move constructor and a move assignment operator really start make a difference?

Considering the high quality of today's compilers regarding return value optimization (both RVO and NRVO), I was wondering at what class complexity it's actually meaningful to start adding move constructors and move assignment operators.

For instance, for this really_trivial class, I just assume that move semantics cannot offer anything more than RVO and NRVO already does when copying around instances of it:

class really_trivial
{
    int first_;
    int second_;

public:

    really_trivial();
    ...
};

While in this semi_complex class, I'd add a move constructor and move assignment operator without hesitation:

class semi_complex
{
    std::vector<std::string> strings_;

public:

    semi_complex(semi_complex&& other);
    semi_complex& operator=(semi_complex&& other);
    ...
};

So, at what amount and of what kinds of member variables does it start making sense to add move constructors and move assignment operators?

like image 530
Johann Gerell Avatar asked Jan 18 '11 12:01

Johann Gerell


People also ask

What is the difference between move constructor and move assignment?

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.

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

The move constructor and move assignment operator are simple. Instead of deep copying the source object (a) into the implicit object, we simply move (steal) the source object's resources. This involves shallow copying the source pointer into the implicit object, then setting the source pointer to null.

Why copy constructor and assignment operator's working is different?

The Copy constructor and the assignment operators are used to initializing one object to another object. The main difference between them is that the copy constructor creates a separate memory block for the new object. But the assignment operator does not make new memory space.

What is the purpose of a move constructor?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying.


2 Answers

It is already meaningful for purely semantic reasons, even if you keep the optimization-aspects out completely. Just imagine the case where a class does not/cannot implement copying. For example boost::scoped_ptr cannot be copied, but it can be moved!

like image 78
ltjax Avatar answered Sep 20 '22 03:09

ltjax


In addition to the excellent answers already given, I would like to add a few forward-looking details:

There are new rules in the latest C++0x draft for automatically generating a move constructor and move assignment operator. Although this idea is not entirely new, the latest rules have only been in the draft since Oct. 2010, and not yet widely available in compilers.

If your class does not have a user-declared copy constructor, copy assignment operator, move constructor, move assignment operator and destructor, the compiler will provide defaulted move constructor and move assignment operator for you. These default implementations will simply member-wise move everything.

You can also explicitly default your move members:

semi_complex(semi_complex&&) = default;
semi_complex& operator=(semi_complex&&) = default;

Note that if you do so, you will implicitly inhibit copy semantics unless you explicitly supply or default the copy constructor and copy assignment operator.

In a closely related late-breaking change: If your class has an explicit destructor, and implicit copy members, the implicit generation of those members is now deprecated (the committee would like to remove the implicit generation of copy when there is an explicit destructor, but can't because of backwards compatibility).

So in summary, any time you have a destructor declared, you should probably be thinking about explicitly declaring both copy and move members.

like image 21
Howard Hinnant Avatar answered Sep 22 '22 03:09

Howard Hinnant