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