3. 右值引用
右值引用是 C++11 引入的一种新的引用类型,用 T && 表示,它用于代替使用 const 类型的左值引用(const T &)来绑定右值,给右值取一个别名,延长右值的生命周期,同时可以窃取右值的资源,从而避免复杂的深拷贝来提高执行效率。
语法
类型 && 引用变量名 = 右值;
示例
#include <iostream>
using namespace std;
int main(int argc, char * argv[]) {
int x = 100;
int &lr_x = x; // 左值引用
// int &lr_e = 200; // 错误,左值引用不能绑定左值
const int &clr = 300; // const 左值引用可以绑定右值(延长生命周期)
int && rr_1 = 400; // 右值引用绑定右值
int && rr_2 = x + 1; // 右值引用绑定右值
// int && rr_3 = x; // 错误右值引用不能绑定左值
return 0;
}
移动语义 std::move
std::move 是 C++11 中一个纯粹的强制类型转换(static_cast),作用是把左值类型无条件转换为右值类型,从而 告诉 编译器,此std::move 函数返回的类型是右值,在函数重载时最匹配的类型是右值引用。
用法:
std::move(obj) // 可以将一个左值(或右值)将其转化为右值。
函数重载决议优先级顺序
- 精确匹配
- 左值/右值引用匹配
- 常量转换
- 其他转换
示例
// filename: override.cpp
#include <iostream>
using namespace std;
void fx(int &x) {
cout << "fx(int &x):" << x << endl;
}
void fx(const int &x) {
cout << "fx(const int &x):" << x << endl;
}
void fx(int &&x) {
cout << "fx(int &&x):" << x << endl;
}
void fx(double x) {
cout << "fx(double x):" << x << endl;
}
int main(int argc, char * argv[]) {
// 右值
int i = 100; // r是右值
int &ri = i; // ri左值引用
const int & cri = i; // cri 是带有const 修饰属性的左值引用
fx(i); // 调用 void fx(int &x);
fx(ri); // 调用 void fx(int &x);
fx(cri); // 调用 void fx(const int &x);
fx(200); // 调用 void fx(int &&x);
fx(cri+1); // 调用 void fx(int &&x);
fx(1+2); // 调用 void fx(int &&x);
fx(std::move(i)); // 调用 void fx(int &&x);
return 0;
}
编译和运行结果如下:
weimz@mzstudio:~$ g++ -o override override.cpp
weimz@mzstudio:~$ ./override
fx(int &x):100
fx(int &x):100
fx(const int &x):100
fx(int &&x):200
fx(int &&x):101
fx(int &&x):3
fx(int &&x):100