C++ 移动构造函数
示例
假设我们有此代码段。
class A { public: int a; int b; A(const A &other) { this->a = other.a; this->b = other.b; } };
要创建一个复制构造函数,即创建一个复制一个对象并创建一个新对象的函数,我们通常会选择上面显示的语法,我们将为A提供一个构造函数,该构造函数将引用另一个类型为A的对象,我们将在方法内部手动复制对象。
或者,我们可以编写A(constA&)=default;使用它的副本构造函数自动复制所有成员的代码。
但是,要创建一个移动构造函数,我们将采用一个右值引用而不是一个左值引用,就像这里一样。
class Wallet { public: int nrOfDollars; Wallet() = default; //默认ctor Wallet(Wallet &&other) { this->nrOfDollars = other.nrOfDollars; other.nrOfDollars= 0; } };
请注意,我们将旧值设置为zero。默认的move构造函数(Wallet(Wallet&&)=default;)复制PO的值nrOfDollars。
由于移动语义旨在允许从原始实例“窃取”状态,因此重要的是考虑这种窃取后原始实例的外观。在这种情况下,如果我们不将值更改为零,我们将使美元数量增加一倍。
Wallet a; a.nrOfDollars = 1; Wallet b (std::move(a)); //calling B(B&& other); std::cout <<a.nrOfDollars<< std::endl; //0 std::cout <<b.nrOfDollars<< std::endl; //1
因此,我们从一个旧的对象开始构造一个对象。
尽管上面是一个简单的示例,但它显示了move构造函数打算做什么。它在更复杂的情况下(如涉及资源管理)变得更加有用。
//管理涉及指定类型的操作。 //在堆上拥有一个助手,并在其内存中拥有一个(大概在堆栈上)。 //这两个助手都是DefaultConstructible,CopyConstructible和MoveConstructible。 template<typename T, template<typename> typename HeapHelper, template<typename> typename StackHelper> class OperationsManager { using MyType = OperationsManager<T, HeapHelper, StackHelper>; HeapHelper<T>* h_helper; StackHelper<T> s_helper; //... public: // Default constructor & Rule of Five. OperationsManager() : h_helper(new HeapHelper<T>) {} OperationsManager(const MyType& other) : h_helper(new HeapHelper<T>(*other.h_helper)), s_helper(other.s_helper) {} MyType& operator=(MyType copy) { swap(*this, copy); return *this; } ~OperationsManager() { if (h_helper) { delete h_helper; } } //移动构造函数(不包含swap())。 // Takes other's HeapHelper<T>*. // Takes other's StackHelper<T>, by forcing the use of StackHelper<T>'s move constructor. // Replaces other's HeapHelper<T>* with nullptr, to keep other from deleting our shiny //销毁时的新帮手。 OperationsManager(MyType&& other) noexcept : h_helper(other.h_helper), s_helper(std::move(other.s_helper)) { other.h_helper= nullptr; } //移动构造函数(使用swap())。 //将我们的成员置于我们希望他人处于的状态,然后切换成员 //和其他人。 // OperationsManager(MyType&& other) noexcept : h_helper(nullptr) { //swap(*this,other); //} //复制/移动助手。 friend void swap(MyType& left, MyType& right) noexcept { std::swap(left.h_helper, right.h_helper); std::swap(left.s_helper, right.s_helper); } };