……是世界上最受推崇、设计最精妙的 C++ 库项目之一。
— Herb Sutter 和 Andrei Alexandrescu, 《C++ Coding Standards》
有些类型不适合复制语义,但仍然可以使其具有移动能力。例如:
unique_ptr
(非共享、不可复制的所有权)通过使这些类型具有移动能力(尽管仍然不可复制),它们的可用性得到了极大的提高。可移动但不可复制的类型可以从工厂函数中按值返回。
file_descriptor create_file(/* ... */); //... file_descriptor data_file; //... data_file = create_file(/* ... */); // No copies!
在上例中,底层文件句柄在对象之间传递,前提是源 file_descriptor
是一个右值。此时,仍然只有一个底层文件句柄,并且同一时间只有一个 file_descriptor
拥有它。
要使用可移植语法编写可移动但不可复制的类型,您需要遵循以下简单步骤:
BOOST_MOVABLE_BUT_NOT_COPYABLE(classname)
BOOST_RV_REF(classname)
的移动构造函数和移动赋值运算符。这是使用可移植语法定义的 file descriptor
:
#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; } };