C++左值和右值(左引用和右引用)
什么是引用?
- 引用实际上就是原有数据的一个别名。
- 引用声明的时候,必须立即初始化,否则报错。
- 引用并不会开辟新的空间,对引用和对原数据取地址得到的地址是一样的。
- 不能创建数组的引用,因为数组是一堆数据,而引用只是表示一个个体的别名。
int age = 18;
int &age2 = age; // age2是age的一个别名
age2 = 88;
cout << "age = " << age << endl; // age = 88
cout << "age2 = " << age2 << endl; // age2 = 88
// 引用声明必须初始化
int age3;
// int &age; // 报异常
// 地址是一样的
int age5 = 6;
cout << "age5 = " << &age5 << endl; // age5 = 0x61fd38
int &age6 = age5;
cout << "age6 = " << &age6 << endl; // age6 = 0x61fd38
// 不能创建数组的引用
int scores[3];
// 禁止创建数组的引用
// int &s2 = scores; // error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int*'
为什么要区分左值和右值?
C++里面的赋值表达式,有左值和右值之分
为什么要区分左引用和右引用,因为函数参数有的要左引用有的要右引用。所以在调用别人系的函数的时候,就要小心一些,因为函数的参数经常会出现左引用和右引用。
左值可以出现在等号的左边也可以出现在右边,右值只能出现在等号的右边。
区分左值和右值就看它能否取地址,能取地址的就是左值,不能取地址的就是右值。
取地址:&age
左值一般是一些变量、对象,因为他会开辟空间,右值其实就是所这个空间里面的数据是实实在在的数值,比如:数值,计算表达,函数的返回值。
int a = 3; // a : 左值, 3 : 右值
&a; // 左值可以取地址
// &3; // 数值 - 右值不能取地址
int b = 4; // b : 左值, 4 : 右值
&b; // 左值可以取地址
// &4; // 数值 - 右值不能取地址
int c = a; // c : 左值, a : 左值
&c; // 左值可以取地址
&a; // 左值可以取地址
int d = 1 + 2; // d : 左值, 1 + 2 : 右值
&d; // 左值可以取地址
// &(1 + 2); // 计算表达 - 右值不能取地址
int e = a + 3; // e : 左值, a + 3 : 右值
&e; // 左值可以取地址
// &(a + 3); // 计算表达 - 右值不能取地址
int getMoney() {
int money = 100;
return money;
}
int m = getMoney(); // e : 左值, getMoney() : 右值
&m; // 左值可以取地址
// &getMoney(); // 函数的返回值 - 右值不能取地址
- 左值引用其实就是以前讲过的引用,使用一个 & 表示
- 左值引用能接收左值,默认不能接收右值,如果要接收右值需要const关键字
using namespace std;
int add02(int &a, int &b) {
return a + b;
}
int main() {
int a = 3; // a : 左值, 3 : 右值
int b = a; // b : 左值, a : 左值
// 左值引用接收右值
const int & d = 3; // d : 左引用, 3 : 右值
}
- 右值引用使用 && 表示。
- 右值引用只能接收右值,禁止接收左值。
int a = 3; // a : 左值, 3 : 右值
int b = a; // b : 左值, a : 左值
// 右值引用禁止接收左值
// int && e = a; // e : 右值引用, a : 左值
// 右值引用只能接收右值
int && f = 3; // f : 右值引用, 3 : 右值
int add01(int a, int b) {
return a + b;
}
int add02(int & a, int & b) {
return a + b;
}
int add03(int && a, int & b) {
return a + b;
}
int add04(int && a, int && b) {
return a + b;
}
int main() {
vector<int> vi;
int a = 3; // a : 左值, 3 : 右值
int b = 5; // a : 左值, 5 : 右值
vi.push_back(a);
vi.push_back(3);
add01(a, 5); // 随便传左值或右值
add02(a, b); // 左引用接收左值
add03(3, b); // 右引用接收右值,左引用接收左值
add04(3, 5); // 右引用接收右值
}