1. 左值引用、右值引用
右值: 只能在 = 右边使用的值
字面量、中间结果、临时对象/匿名对象
无法取地址,不能使用左值引用
左值: 可以在 = 左边使用的值
编程,观察现象:
#include <iostream>
using namespace std;
void Print(int n){
cout << n << endl;
}
void Print2(int& n){
// 左值引用
cout << n << endl;
}
void Print3(const int& n){
// 解决左值引用问题
cout << n << endl;
}
void Print4(int&& n){
// 右值引用
cout << n << endl;
}
int main(){
int n = 10;
int m = n;
// 10 = n; // 10为右值,字面量
const char* s = "123edf";
// "abcd" = s; // "abcd"为右值,字面量
m = n + 2;
// n + 2 = m; // n + 2 为右值,中间结果
string str = string(s);
// string(s) = str; // string(s)为右值,临时对象
Print(m); // int n = m;
Print(10); // int n = 10;
Print2(m); // int& n = m;
// Print2(10); // int& n = 10; // 字面量(右值)不能初始化左值引用
Print3(m); // const int n = m;
Print3(10); // const int n = 10; // 补丁:const左值引用可以初始化左值和右值
// Print4(m); // int&& n = m; // 左值不能初始化右值引用
Print4(10); // int&& n = 10;
}
结果为:
12
10
12
12
10
10
- 10为字面量,为右值
- “abcd”为字面量,为右值
- n+2为中间结果,为右值
- string(s)为临时对象,为右值
- 普通函数传值,左值右值都可以传
- 10为右值,不能初始化左值引用
- 加const,右值也可以初始化左值引用,即左右都可
- m为左值,不能初始化右值引用
2. 移动构造函数、移动赋值运算符重载
2.1 不可拷贝对象的移动
对于不可拷贝对象,可以使用移动语法做拷贝构造和赋值。
移动的条件:
- 只有右值才能移动,如果左值要移动需要转换成右值
move( )
,或者使用匿名对象Uncopy()
- 对象的类要实现移动构造函数和移动赋值运算符重载
#