Possible Duplicate:
How can moved objects be used?
What constitutes a valid state for a “moved from” object in C++11?
When implementing move semantics in C++11, should the moved-from object be left in a safe state, or can it be just left in a "junk" state?
e.g. What is the preferred option to implement move constructor in the following example of a C++11 wrapper to a raw FILE*
resource?
// C++11 wrapper to raw FILE*
class File
{
FILE* m_fp;
public:
// Option #1
File(File&& other)
: m_fp(other.m_fp)
{
// "other" left in a "junk" state
}
// Option #2
File(File&& other)
: m_fp(other.m_fp)
{
// Avoid dangling reference in "other"
other.m_fp = nullptr;
}
...
};
Rust requires implementations for clone, but for all moves, the implementation is the same: copy the memory in the value itself, and don't call the destructor on the original value. And in Rust, all types are movable with this exact implementation – non-movable types don't exist (though non-movable values do).
The only thing you must be able to do with a moved-from object is destroy it. Beyond that, it's up to your class what the normal class invariants are and whether moved-from objects bother to satisfy them.
For example, it's a good idea to ensure that you can assign to the object, just in case someone wants to use std::move
on an instance and give it a new value later. [Edit: as pointed out in an answer to one of the suggested-dupe questions, the general std::swap
template moves from an object and then move-assigns to it, so if you don't ensure this then either you need to specialize std::swap
or you need to forbid users of your class from using it.]
Since your class does nothing in its destructor, either option is fine. Option 2 might be easier for users to work with, but then again if they're coding on the assumption that they can't do anything with a moved-from object, then it makes no difference. Since the class is incomplete, though, that might change when you write the destructor.
An object that has been moved from is still an object, and it must be in a valid state, although it may be indeterminate. In particular, it should be possible to assign a new value to it safely (and of course it must be destructible, as @Steve says). It's up to you what particular semantics you want to give your class, as long as a moved-from object remains valid.
In general, you should think of "move" as an optimized "copy". However, for some classes that are intrinsically "move-only", such as unique_ptr
, additional guarantees may be appropriate – for example, unique_ptr
promises that after it has been moved-from it is null, and surely nothing else really makes sense.
(Your actual code is incomplete, but given that a FILE*
is a sort-of move-only resource, it is probably broken and you should try to emulate unique_ptr
as closely as possible – or even use it directly.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With