引用作为对象的别名存放的是对象的机器地址
引用最重要的用途是作为函数的实参或返回值,被用于重载运算符
左值可以出现在赋值语句的左边和右边;右值只能出现在赋值语句的右边,不能出现在赋值语句的左边。
左值可以获取地址,右值不可以
7.7.1 左值引用
左值引用:引用那些我们希望改变值的对象
const引用:引用那些我们不希望改变值的对象
表示方法(X的引用):X&
初始化引用:
int var=1;
int& r1{var}; //ok:初始化r1
int& r2; //缺少初始化器
extern int& r3; //ok:r3在别处初始化
给引用赋值:
void g()
{
int var=0; //var:0, &var:000000340A15F694
int& rr {var}; //rr:0, &rr:000000340A15F694
++rr; //var的值加1, rr:1, &rr:000000340A15F694, var:1
int* pp=&rr; //pp指向var, pp:1, *pp:1
}
var的地址、rr的地址、加1后rr的地址都一样
++rr的含义不是递增引用rr,而是给rr所引的int(即var)加1
引用本身的值一旦经过初始化就不能再改变,即&rr不改变
可以使用&rr得到一个指向rr所引对象的指针,即pp
当初始值是左值时,提供给T&的初始值必须是T类型的左值。
const T&的初始值不一定非得是左值,甚至可以不是T类型的。(实际代码似乎会报错)
double& dr=1; //错误:需要左值
const double& cdr{1}; //ok
const double& cdr{1}; 可以理解为
double temp=double {1}; //首先用给定的值创建一个临时变量
const double& cdr {temp}; //然后用这个临时变量作为cdr的初始值
普通变量的引用和常量的引用必须区分开来
7.7.2 右值引用
右值引用:所引对象的值在我们使用之后就无须保留了(比如临时变量)
非常量引用的初始值必须是左值
表示方法(X的引用):X&&