When we move an object with by std::move
No. std::move
doesn't move things. It gives us an rvalue expression referring to some object. An rvalue expression results in overload resolution picking functions that take rvalue references, which is convenient because now we will pick those instead of the functions that take values, or lvalue references, which traditionally do copy-like things. Such functions tend to be constructors (so-called "move constructors") or assignment operators (so-called "move assignment operators") because it is during construction and assignment that moving is useful.
it makes the object nullptr
That depends entirely on what said function does. Typically, an object that's worth moving has indirect state, like a pointer to some dynamically-allocated resource. And if said object is moveable, its move constructor is best off doing a swap on those pointers. If it didn't leave the source object's pointer as nullptr
then you have two objects owning the resource. That wasn't a move; it was a [shallow] copy.
A full discussion of the hows and the whys is out of scope of a Q&A, but any good book should have one.
Also, if this all sounds like a hack, that's because it is one. C++ is a hodge-podge of hacks built on hacks to provide additional functionality over time. In this case, we needed (read: wanted) a way to create a different kind of constructor (and assignment operator), a kind that would take a non-const
reference and could modify the source object (to "steal" its resources), and to achieve that we had to introduce a new kind of reference that would only bind to rvalues (because we were already using everything else for copies), and then we had to introduce a utility function that would turn the name of an object into an rvalue … hence, std::move
was born, the utility function that doesn't move anything.