What exactly does it mean to say a C++ object is movable?
The act of 'moving of an object' is analogous to the act of 'selling a house'. The object remains stationary. Only the title (ownership) changes hands.
The concept of moving an object in C++ is one of the implementations of the well known 'pass-by-reference' method. This can be explained easily by a real example.
An Internet Router is one of the best examples to describe this concept of moving an object. Suppose that a router with 4 interfaces has received a packet of data (IP packet) via one of its interfaces. Now, the router has to look up its routing table, apply security policies, apply NAT rules, etc on the packet before sending it out of one of its interfaces.
The router will create only one copy of the data packet in the memory and pass its reference to different sub-systems (Route table, NAT, Security, QoS, etc). Each sub-systme of the router will operate on the packet and pass it on to the next sub-system, till the packet gets sent out of the router, towards the destination. Memory will be cleaned up when the packet leaves the router.
In this scenario, the different sub-systems of router gain control over the same packet object at different times. The packet object remains at a single memory location throughout the processing. It never gets copied. This method of passing ownership of an object to different sub-systems / functions can be seen as 'moving the object'. However, in practice, the object had stayed where it is, but the control of object had moved across sub-systems.
(Similar to how the ownership of a house gets transferred when it is sold.)
- What does "move its value to another location" really mean?
It means that the other location has the value that the original had prior to the move, and that it is not important what value the original location has after the move.
- How can a value (a bit interpretation) be moved?
For example, simply by copying. If one wanted to do extra work beyond that (which is not motivated with just a bag of bits), one could set the original location to some other bit pattern, such as all zeroes, and it would still be considered a successful move. The difference here with copying is that a copy should leave the original unchanged.
- How can bytes of an object be "moved" without a copy? Just doesn't make sense.
A copy is a valid move.
Sometimes the bits in the original have semantics of owning a resource. If there is only one resource, and you simply copy the bits, now both locations "own" the resource, resulting in duplicate disposing of said resource when both objects go out of scope.
So a move would transfer ownership of the resource to the new location and change the original location to not own a resource. A concrete example of this is an owning pointer: copy the pointer then set the original to nullptr
.
A copy might be more expensive than a move (and it might not). But continuing with the owning pointer example: If you make a copy of that object, then after the copy, two resources must exist (assuming unique ownership of the resource).
So a copy doesn't copy the pointer. The copy copies the resource and then the new location points to the new resource. If the creation of that resource is expensive, then a move can be much cheaper by just copying the pointer and nulling the original.
Generally speaking, move should be an optimization of copy when the type supports both operations. move should never be more expensive than copy. And if move has the same expense as copy, then the move operations can simply be not implemented and copy will handle moves seamlessly. It is up to the author of each type to maintain this paradigm.
For scalars (ints, pointers, doubles, etc.) copy and move are the same thing: copy the bits, don't alter the source.