The idea behind move semantics is that in the case where
a.) an object owns some resource
b.) that object needs to be copied
c.) the object to be copied no longer needs its resources (e.g., because it is about to be destroyed)
It's often possible to "steal" the resources of the original object (i.e., to perform a "destructive" or shallow copy) under the assumption that the original object will no longer be in use.
A move constructor performs the same function as the copy constructor, except that the source object is left "empty" (in general, in an unspecified but valid state) after a move instead of a copy.
Move operations are also useful in situations where it does not make sense to have multiple copies of an object; however we may still want to transfer the ownership of the object to another component. Examples of objects which can't be copied, but may be moved include: threads, file streams, and windows on a screen.
For instance, move semantics makes it possible for us to have a vector of file streams; when the vector performs a reallocation, the file streams it holds can be moved to the new location.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
std::vector<std::ifstream> vec ;
vec.push_back( std::ifstream{ __FILE__ } ) ;
std::cout << "the file stream vec[0] is at address "
<< std::addressof( vec[0] ) << '\n' ;
vec.resize(100) ;
std::cout << "the file stream vec[0] is moved to address "
<< std::addressof( vec[0] ) << '\n' ;
}