一、右值引用
本身是左值,可以引用右值,接管临时对象的资源。
左值引用不能引用右值,右值引用不能引用左值。
// 左值引用
int a = 10;
int &b = a; // 引用的是一个左值
// 右值引用
int a = 10;
int &&b = a + 1; // 引用 a+1 是一个表达式,结果是一个右值
int &&c = 12; // 引用一个字面值,是右值
int &&d = max(10, 11); // 引用一个非引用类型的函数返回值,是右值
class A{
public:
int a;
A():a(0){}
};
A fun(){
retrun A(); // 构造临时对象,产生一个无名的临时对象,右值
}
A t1 = fun(); // 构造新对象t1,拷贝临时对象的资源,销毁临时对象
A && t2 = fun(); // 接管临时对象的资源,引用右值
二、移动语义
移动的目的是在小开销下进行资源转让,避免赋值过程中 拷贝对象资源、销毁对象 的开销。左值引用起到了共享资源的目的,右值引用是接管了原临时对象的资源。
将对象A的资源以及对其资源的管理权完全转移给对象B,对象A之后变为裸对象。
对象A作为移交者,多是临时对象,如表达式的值、函数非引用返回值、字面值等。
对象B作为接收者,可以是右值引用、常(左值)引用。
(1)右值实现移动语义
直接使用右值引用。
(2)左值实现移动语义
先将左值转化为右值,然后使用右值引用。
参考链接: