c++11——移动语义的举例说明
目录
一、移动语义(进行资源的转移)
1.定义
2.实现方式
二、右值和右值引用
1.右值
2.右值引用(&&)
三、移动构造函数
四、移动赋值运算符
五、std::move() 函数
1.本质
2.强调
一、移动语义(进行资源的转移)
1.定义
是一种优化技术,核心是将资源的所有权从一个对象转移到另外一个对象,而不必进行代价高昂的深拷贝操作,避免不必要的内存分配和数据复制。
2.实现方式
通过右值引用和移动构造函数/移动赋值运算符实现。也就是说:
移动语义需要满足两个条件:
①转化为右值引用
②存在移动构造函数/移动赋值运算符。
二、右值和右值引用
1.右值
指表达式结束后就不再存在的临时对象。不能对右值取地址。
右值又分为:纯右值(字面常量)和将亡值。
2.右值引用(&&)
右值引用是对右值的引用,使用&&表示,允许捕获并操作临时象。
三、移动构造函数
移动构造函数允许对象在创建时接管另一个对象的资源。
以MyString类为例,解释移动构造函数:
①先将s1(左值)通过std::move()强制转换为右值引用;
②然后调用对象的移动构造函数,实现资源的转移。
四、移动赋值运算符
移动赋值运算符允许对象在赋值时接管另一个对象的资源。
(1)以MyString类为例,解释移动赋值运算符:
①先将s1(左值)通过std::move()强制转换为右值引用;
②然后调用对象的移动赋值运算符,将堆区中的资源移动给另外一个对象,实现资源的转移。
(2)从下图也可以发现:
采用深赋值的方式(s2=s1),需要先将原本的堆空间进行释放,释放后又需要在堆区中重新开辟一块内存,而采用移动赋值(s3=std::move(s1))可以减少对堆区的操作。
五、std::move() 函数
1.本质
是C++标准库中的一个工具,核心作用是将左值强制转换为右值引用。
本质是一个类型转换函数,无论参数原本是左值还是右值,都会被转换为右值引用
注意:std::move本身并不执行移动操作,移动操作发生在后续调用的移动构造函数或移动赋值运算符中。
2.强调
std::move()函数不能将const对象转换为右值引用。
原因:
如果对象本身是const,转化后类型变为const T&&(常量右值引用),而移动构造函数/赋值运算符需要修改源对象的状态,要求参数通常是非const右值引用。因此无法调用移动操作。
当对 const
对象使用 std::move
时,编译器会选择 拷贝构造函数 而非移动构造函数(拷贝构造函数可以接受 const T&
参数)。