Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between the move assignment operator and move constructor?

For some time this has been confusing me. And I've not been able to find a satisfactory answer thus far. The question is simple. When does a move assignment operator get called, and when does a move constructor operator get called?

The code examples on cppreference.com yield the following interesting results:

The move assignment operator:

a2 = std::move(a1); // move-assignment from xvalue

The move constructor:

A a2 = std::move(a1); // move-construct from xvalue

So has it do to with which is implemented? And if so which is executed if both are implemented? And why is there the possibility of creating a move assignment operator overload at all, if it's identical anyway.

like image 727
laurisvr Avatar asked Apr 30 '15 15:04

laurisvr


People also ask

What is the difference between move constructor and copy constructor?

Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.

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.

What is a move constructor?

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 is the difference between the Move and Copy operator?

The subtle difference is, if you create with a copy or move semantic a new object based on an existing one, that the copy semantic will copy the elements of the resource, that the move semantic will move the elements of the resource.


3 Answers

A move constructor is executed only when you construct an object. A move assignment operator is executed on a previously constructed object. It is exactly the same scenario as in the copy case.

Foo foo = std::move(bar); // construction, invokes move constructor
foo = std::move(other); // assignment, invokes move assignment operator

If you don't declare them explicitly, the compiler generates them for you (with some exceptions, the list of which is too long to be posted here).

See this for a complete answer to when the move member functions are implicitly generated.

like image 83
vsoftco Avatar answered Oct 07 '22 17:10

vsoftco


When does a move assignment operator get called

When you assign an rvalue to an object, as you do in your first example.

and when does a move constructor operator get called?

When you initialise an object using an rvalue, as you do in your second example. Although it isn't an operator.

So has it do to with which is implemented?

No, that determines whether it can be used, not when it might be used. For example, if there's no move constructor, then construction will use the copy constructor if that exists, and fail (with an error) otherwise.

And if so which is executed if both are implemented?

Assignment operator for assignment, constructor for initialisation.

And why is there the possibility of creating a move assignment operator overload at all, if it's identical anyway.

It isn't identical. It's invoked on an object that already exists; the constructor is invoked to initialise an object which previously didn't exist. They often have to do different things. For example, assignment might have to delete something, which won't exist during initialisation.

like image 22
Mike Seymour Avatar answered Oct 07 '22 16:10

Mike Seymour


This is the same as normal copy assignment and copy construction.

A a2 = std::move(a1);
A a2 = a1;

Those call the move/copy constructor, because a2 doesn't yet exist and needs to be constructed. Assigning doesn't make sense. This form is called copy-initialization.

a2 = std::move(a1);
a2 = a1;

Those call the move/copy assignment operator, because a2 already exists, so it doesn't make sense to construct it.

like image 22
TartanLlama Avatar answered Oct 07 '22 18:10

TartanLlama