...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Some types are not amenable to copy semantics but can still be made movable. For example:
unique_ptr
(non-shared,
non-copyable ownership)
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:
BOOST_MOVABLE_BUT_NOT_COPYABLE(classname)
BOOST_RV_REF(classname)
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; } };