一、move函数
move函数本质是可将一个左值转化为右值,或将一个右值转化为左值
与强转函数类似
但是,move函数无法消除const,即move无法对一个常性左值,或常性右值 ,进行类型转换
给出示例:
构建一个Int类,此处仅展示main函数部分
int main()
{
Int a(10);//a是左值
Int&& ra = (Int &&)a;//ra是右值引用,利用强转,使得左右类型一致
Int&& rb = std::move(a);//移动函数,将左值a 类型转为右值,但是移动函数无法消除const
const Int c(10);
Int&& rc =(Int &&) c;
Int&& rd = std::move(c);//error move不可消除const
}
二、移动拷贝构造函数
设计类MyString,数据成员char * str , 此处省略类设计
//移动拷贝构造
MyString(MyString &&s):str(s.str)
{
s.str = nullptr;
}
int main()
{
MyString s1("hello");
MyString s2(std::move(s1));//移动构造s2
//最后一行等价于MyString s2((MyString&&)s1);将左值a转换成右值,所以需要参数为右值引用的拷贝构造函数来创建对象s2
}
图解移动构造函数:
移动构造函数 与 浅构造函数的区别:
浅构造函数MyString s3(s1) ;不会将s1置空,即构造对象s3后,s3和s1共同指向堆区
而移动构造函数,给s1置空,此时s1与堆区hello已经没有关系了
总结:本质是一个深拷贝(即需要在堆区开辟空间)
三、移动赋值
MyString& operator=(MyString&& s)
{
if (this != &s && this->str != s.str)
{
delete[]this->str;
this->str = s.str;
s.str == nullptr;
}
return *this;
}
int main()
{
MyString s1("abc");
MyString s("cde");
s = std::move(s1);
}
图解移动赋值: