Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::move inside move assignment operator

Tags:

c++

c++11

move

I read in another question that when implementing a move constructor it is good practice to std::move each member in the initializer list because if the member happens to be another object then that objects move constructor will be called. Like 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 move assignment operators I've seen, there has been no mention of using std::move for the same reasons. If the member is an object then should std::move be used? Like 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 there is no need to use std::move in the example I have chosen (poorly) however I'm interested in if the members were objects.

like image 925
TomP89 Avatar asked Nov 15 '12 20:11

TomP89


2 Answers

After reading the linked question, I can see the advice in the second most-upvoted answer is to use std::move in the initializer list for the move constructor because no matter if it is a primitive type or not, it will do the right thing. I somewhat disagree with that and think you should only call std::move where appropriate, but this is were personal preferences come in.

Also, for your move assignment operator, the way you have it is fine although I think the unnecessary call to std::move should be removed personally. Another option is to use std::swap which will do the right thing for you.

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

The difference between the above move assignment operator and your move assignment operator is that the deallocation of memory is delayed while your version deallocates the memory right away, this might be important in some situations.

like image 164
Jesse Good Avatar answered Oct 19 '22 21:10

Jesse Good


It looks like prBuffer is a pointer and prBufferLength is some kind of integral type, so move isn't going to make any difference in this particular case as they are both fundamental types.

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

like image 1
Alex Korban Avatar answered Oct 19 '22 19:10

Alex Korban