2

I am new to C++, and just learning about move semantics. So from what I understand, using the move constructor I can do something like

MyObj obj1;
MyObj obj2 = std:move(obj1);

And we have to define our own move constructor that cleans up obj1 etc.

It seems we can instead have obj2 be a reference to obj1 if we know that obj1 will not be destroyed before obj2 is done being used. But otherwise, can't we just use an unique_ptr instead? Such that we just create an unique pointer for obj1 and then pass this pointer instead of trying to move the object?

Is there some cases I am not considering?

HTNW
  • 27,182
  • 1
  • 32
  • 60
user3504410
  • 173
  • 1
  • 13
  • @SergeyA That's why it's a comment. I've edited it, OP can look up why the parentheses need to go. (The other solution is to use braces: `MyObj obj1{};`.) – HTNW Jul 13 '20 at 22:40
  • 2
    I think this question comes down to [ownership](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers). Move is a transfer of ownership. Very different from a reference which establishes an alternate name for an existing variable. A `unique_ptr` represents ownership. If you pass a pointer around, you're still in the same world as passing a reference around. The object is owned by someone else. If you want to transfer ownership from one `unique_ptr` to another, you're right back to moving. – user4581301 Jul 13 '20 at 22:54
  • If you're moving stuff to prevent copying, whether you move or use a pointer depends a lot on whether or not the object can benefit from moving. – user4581301 Jul 13 '20 at 22:55
  • @user4581301 so would it be correct to say that in the example i listed, wrapping `obj1` in a unique pointer would make it so that i don't need to explicitly define move constructor and move assignment operator for my `myObj` class. However, I am still using `std::move` regardless, just on a `unique_ptr` object instead of a `MyObj` object?? – user3504410 Jul 13 '20 at 23:08
  • 1
    Yes, but "Which better describes the behaviour I want?" should be asked before selecting either. If performance is your key concern, Profile. Also ask "Is it more expensive to bring dynamic allocation into this job?" It may be cheaper to move once, even if the move is expensive, than pointer-chase forever. If you just want to avoid writing a potentially complex move constructor (Copy and Swap makes move assignment dead easy) sooner or later someone's going to use the code without a pointer and uncover the flaws. – user4581301 Jul 13 '20 at 23:22

1 Answers1

3

From the example you provided I agree you could use a reference here or even a shared_ptr but it really depends on your use case.

However, move semantics are very handy in expressing a change of ownership. For example suppose obj1 is some resource (think database connection, a file you are writing too, etc). And now consider the following:

int func1() {
   MyObj obj1;
   // do something with obj1
   func2(std::move(obj1));
   // do some other stuff without obj1
   return 0;
}

in the third line of func1 we transfer the ownership of obj1 to func2. After this line, func1 no longer owns obj1 and should not use it whereas func2 can do whatever it needs to do with obj1.

This is especially useful for resources, like a file, where func1 could do something with the file and then have func2 do something else. By using std::move it's kind of like a contract that func1 won't modify this object anymore. This prevents func1 from potentially overwriting the work done by func2

mattyx17
  • 806
  • 6
  • 11