Moving from an object just means that the moved-from object might donate its guts to live on in another live object shortly before it is [probably] going to die. Note, however, that just because an object donated its guts that the object isn't dead! In fact, it may be revived by another donating object and live on that object's guts.
Also, it is important to understand that move construction or move assignment can actually be copies! In fact, they will be copies if the type being moved happens to be a pre-C++11 type with a copy constructor or a copy assignment. Even if a class has a move constructor or a move assignment it may choose that it can't move its guts to the new object, e.g., because the allocators mismatch.
In any case, a moved from object may still have resources or need to record statistics or whatever. To get rid of the object it needs to be destroyed. Depending on the class's contracts it may even have a defined state after being moved from and could be put to new use without any further ado.
"The Rule of Zero" is in fact about something else than what special member functions are generated and when. It is about a certain attitude to class design. It encourages you to answer a question:
Does my class manage resources?
If so, each resource should be moved to its dedicated class, so that your classes only manage resources (and do nothing else) or only accumulate other classes and/or perform same logical tasks (but do not manage resources).
It is a special case of a more general Single Responsibility Principle.
When you apply it, you will immediately see that for resource-managing classes you will have to define manually move constructor, move assignment and destructor (rarely will you need the copy operations). And for the non-resource classes, you do not need to (and in fact you probably shouldn't) declare any of: move ctor/assignment, copy ctor/assignment, destructor.
Hence the "zero" in the name: when you separate classes to resource-managing and others, in the "others" you need to provide zero special member functions (they will be correctly auto-generated.
There are rules in C++ what definition (of a special member function) inhibits what other definitions, but they only distract you from understanding the core of the Rule of Zero.
For more information, see:
- https://akrzemi1.wordpress.com/2015/09/08/special-member-functions/
- https://akrzemi1.wordpress.com/2015/09/11/declaring-the-move-constructor/
Best Answer
The first destructor destroys the moved-from
tmp
when it goes out of scope at the first}
inmain()
. The second destructor destroys the move-constructedfoo
that youpush_back
'd intov
at the end ofmain()
whenv
goes out of scope.The compiler-generated move constructor move-constructs
id
, which is astd::string
. A move constructor ofstd::string
typically takes ownership of the block of memory in the moved-from object storing the actual string, and sets the moved-from object to a valid but unspecified state (in practice, likely an empty string).