7.3.7转移行为
转移构造,转移构造的目的在于独占(霸占)源对象中指针成员所指向的内存,所以它要求源对象(例中的other)“签字画押”,白纸黑字地表明“是我自愿放弃我的堆成员所占的内存,并将其所有权转移给新对象,我自愿让我的堆成员回归为空指向”。
#include <iostream>
using namespace std;
struct MyPtr
{
explicit MyPtr(int value)
: ptr(new int(value))
{
cout << "调用了" << __func__ << "的入参构造"
<< ",入参是:" << value << endl;
}
~MyPtr()
{
delete ptr;
}
//禁止复制构造和复制赋值,复制构造和复制赋值,需要保持源对象不变,所以参数需要使用const修饰
MyPtr(MyPtr const& other) = delete; //禁止复制构造
MyPtr& operator = (MyPtr const& other) = delete; //禁止复制赋值
//转移构造,转移构造的目的在于独占(霸占)源对象中指针成员所指向的内存,所以它要求源对象(例中的
//other)“签字画押”,白纸黑字地表明“是我自愿放弃我的堆成员所占的内存,并将其所有权转移给新对象,
//我自愿让我的堆成员回归为空指向”。
MyPtr(MyPtr&& other) //参数没有const修饰,&&是右值引用
: ptr(other.ptr)
{
cout << "调用了" << __func__ << "的转移构造" << endl;
other.ptr = nullptr;
}
//转移赋值
MyPtr& operator = (MyPtr&& other) //参数没有const修饰,&&是右值引用
{
cout << "调用了" << __func__ << "的转移赋值" << endl;
if(ptr != other.ptr)
{
ptr = other.ptr;
other.ptr = nullptr;
}
return * this;
}
//友元,重写 << 符,用于输出
friend ostream& operator << (ostream& os, MyPtr& mp)
{
os << "得到的MyPtr对象的ptr指向:" << mp.ptr
<< " 值为:" << *mp.ptr << endl;
return os;
}
int * ptr;
};
int main()
{
MyPtr mip(5);
cout << mip;
cout << "------------1------------" << endl;
MyPtr mip_2(10);
cout << mip_2;
cout << "---------转移之后----------" << endl;
//使用转移构造,创建mip_3对象,mip_3将抢夺mip的ptr成员
//将mip强制类型转换为MyPtr&&类型,下面的代码才会是转移构造
MyPtr mip_3(static_cast<MyPtr&&>(mip));
cout << mip_3;
//再查看mip的ptr成员是否变为了空
cout << (mip.ptr == nullptr) << endl;//输出为1,mip.ptr已为空
//此时不能直接访问mip,
//为了方便输入,C++标准库提供了一个特定的move函数,用于代替"static_cast"转换
//我们使用std::move()函数来抢夺mip_2
cout << "使用std::move()函数来完成转移" << endl;
MyPtr mip_4(std::move(mip_2));
cout << mip_4;
cout << (mip_2.ptr == nullptr) << endl;
return 0;
}
运行结果为: