Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Movable but Non-Copyable Types

Some types are not amenable to copy semantics but can still be made movable. For example:

By making such types movable (though still non-copyable) their utility is tremendously increased. Movable but non-copyable types can be returned by value from factory functions:

file_descriptor create_file(/* ... */);
//...
file_descriptor data_file;
//...
data_file = create_file(/* ... */);  // No copies!

In the above example, the underlying file handle is passed from object to object, as long as the source file_descriptor is a rvalue. At all times, there is still only one underlying file handle, and only one file_descriptor owns it at a time.

To write a movable but not copyable type in portable syntax, you need to follow these simple steps:

Here's the definition of file descriptor using portable syntax:

#include <boost/move/utility_core.hpp>
#include <stdexcept>

class file_descriptor
{
   int os_descr_;

   private:
   BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)

   public:
   explicit file_descriptor(const char *filename)              //Constructor
      : os_descr_(operating_system_open_file(filename))
   {  if(!os_descr_) throw std::runtime_error("file not found");  }

   ~file_descriptor()                                          //Destructor
   {  if(os_descr_)  operating_system_close_file(os_descr_);  }

   file_descriptor(BOOST_RV_REF(file_descriptor) x)            // Move ctor
      :  os_descr_(x.os_descr_)
   {  x.os_descr_ = 0;  }

   file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
   {
      if(os_descr_) operating_system_close_file(os_descr_);
      os_descr_   = x.os_descr_;
      x.os_descr_ = 0;
      return *this;
   }

   bool empty() const   {  return os_descr_ == 0;  }
};


PrevUpHomeNext