Std :: move within the account assignment operator

I read in another question that when implementing the constructor move, it is good practice for std :: to move each member to the list of initializers, because if the member is another object, after which the constructor of the objects will be called. So ...

//Move constructor Car::Car(Car && obj) : prBufferLength(std::move(obj.prBufferLength)), prBuffer(std::move(obj.prBuffer)) { obj.prBuffer = nullptr; obj.prBufferLength = 0; } 

However, in all the sample assignment operations that I saw, the use of std :: move was not mentioned for the same reasons. If the element is an object, then use std :: move? So ...

 //Move assignment Car Car::operator=(Car && obj) { delete[] prBuffer; prBufferLength = std::move(obj.prBufferLength); prBuffer = std::move(obj.prBuffer); obj.prBuffer = nullptr; obj.prBufferLength = 0; return *this; } 

UPDATE:

I appreciate that there is no need to use std :: move in the example I selected (bad), but I wonder if the members were objects.

+6
source share
5 answers

After reading the related question, I see that the advice in the second most common answer is to use std::move in the list of initializers for the move constructor, because whether it is a primitive type or not, it will do the right thing. I somewhat disagree with this and think that you only need to call std::move , if necessary, but these were personal preferences.

Also, for your forwarding destination operator, the way you have it is fine, although I believe that an unnecessary call to std::move should be deleted personally. Another option is to use std::swap , which will do everything right.

 Car Car::operator=(Car && obj) { std::swap(this->prBufferLength, obj.prBufferLength); std::swap(this->prBuffer, obj.prBuffer); return *this; } 

The difference between the specified forwarding assignment operator and the forwarding assignment operator is that freeing memory is delayed when your version immediately frees memory, which can be important in some situations.

+3
source

It looks like prBuffer is a pointer, and prBufferLength is some kind of integral type, so move will not make any difference in this particular case, since they are both fundamental types.

If prBuffer was std::string , for example, you should use move to force use the move constructor or move the assignment operator.

+1
source

Like so many things in C ++ and in life, there is no definitive yes or no answer to the question.

However, as a rule, if the incoming member is cleared / reset / emptied and assigning the incoming member to the recipient member will cause the assignment operator to be called, then you will want to use std :: move so that the move destination operator will be called instead of the copy assignment operator.

If the assignment operator is not called (i.e. only a shallow copy will be executed), the use of std :: move is not required.

+1
source

If your participating objects benefit from relocation, you must move them. Another strategy that has been demonstrated in the answer you are involved with is sharing. Moving is like moving, but it moves in both directions. If your class manages the resource, this causes the object that was passed (rvalue) to receive unnecessary data. This data is then destroyed by this object destructor. For example, your move destination statement could be written as follows:

 Car Car::operator=(Car && obj) { // don't need this, it will be handled by obj destructor // delete[] prBuffer; using std::swap; swap(prBuffer, obj.prBuffer); swap(prBufferLength, obj.prBufferLength); return *this; } 

Also consider the Copy-and-Swap idiom. This allows you to use the same assignment operator for moving and copying, but has a slight drawback that self-tasking leads to an unnecessary copy.

+1
source

I believe that the best way to implement the transfer destination is to use the move constructor to create a new temporary object, and then swap it with the current object, just like with the copy destination.

It not only avoids code duplication, but also prevents accidental errors, for example. forgetting to move the item.

0
source

All Articles