Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should the moved-from object be left in a "safe" state? [duplicate]

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;
  }

  ...
};
like image 280
Mr.C64 Avatar asked Oct 30 '12 11:10

Mr.C64


People also ask

Does Rust have move semantics?

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).


2 Answers

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.

like image 121
Steve Jessop Avatar answered Jan 10 '23 22:01

Steve Jessop


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 in­trin­sically "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.)

like image 36
Kerrek SB Avatar answered Jan 10 '23 23:01

Kerrek SB