Difference between move assignment operator and move constructor?

For some time this confused me. And while I could not find a satisfactory answer. The question is simple. When does the move assignment operator call and when does the move constructor operator call?

The cppreference.com code examples provide the following interesting results:

Transition Assignment Operator:

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

Move constructor:

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

So it is, with what is implemented? And if so, then what happens if both are implemented? And why is it possible to create an overload of the assignment operator in general if it is all the same identical.

+6
source share
4 answers

The move constructor is executed only when creating an object. The move assignment operator is executed on a previously constructed object. This is exactly the same scenario as with the copy.

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

If you do not declare them explicitly, the compiler creates them for you (with some exceptions, the list of which is too long to publish here).

See this for a complete answer on when functions of a move element are implicitly generated.

+11
source

When a transition assignment operator receives a call

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

and when does the move constructor operator get called?

When you initialize an object using rvalue, as in the second example. Although this is not an operator.

So it is, with what is implemented?

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

And if so, then what happens if both are implemented?

Assignment operator for assignment, constructor for initialization.

And why is it possible to create an overload of an assignment operator in general if it is identical anyway.

It is not identical. It is called on an object that already exists; the constructor is called to initialize an object that did not previously exist. They often have to do different things. For example, an assignment might need to remove something that would not exist during initialization.

+4
source

This is the same as the usual purpose of a copy and building a copy.

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

Those who invoke the move / copy constructor because a2 does not exist yet and needs to be constructed. Appointment does not make sense. This form is called copy-initialization.

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

They call the assignment operator move / copy, because a2 already exists, so it makes no sense to create it.

+2
source

Constructor movement is called during:

  • initialization: T a = std :: move (b); or T a (std :: move (b)) ;, where b is of type T;
  • Passing an argument to a function: f (std :: move (a)); where a is of type T and f is void f (T t);

A move assignment operation is called during:

  • return function: return a; inside a function like T f (), where a is of type T, which has a move constructor.
  • Appointment

The following code example illustrates this:

 #include <iostream> #include <utility> #include <vector> #include <string> using namespace std; class A { public : A() { cout << "constructor called" << endl;} ~A() { cout << "destructor called" << endl;} A(A&&) {cout << "move constructor called"<< endl; return;} A& operator=(A&&) {cout << "move assignment operator called"<< endl; return *this;} }; A fun() { A a; // 5. constructor called return a; // 6. move assignment operator called // 7. destructor called on this local a } void foo(A){ return; } int main() { A a; // 1. constructor called A b; // 2. constructor called A c{std::move(b)}; // 3. move constructor called c = std::move(a); // 4. move assignment operator called a = fun(); foo(std::move(c)); // 8. move constructor called } 

Output:

 constructor called constructor called move constructor called move assignment operator called constructor called move assignment operator called destructor called move constructor called destructor called destructor called destructor called destructor called 
0
source

Source: https://habr.com/ru/post/986310/


All Articles