关于常量引用,左值引用,右值引用的一些理解

简单理解

代码块1:

1
2
3
double dval = 3.14;
// 使用右值引用接受隐式转换产生的临时量(字面量)
int &&rd = dval;

代码块2:

1
2
3
4
5
6
double dval = 3.14;
const int &ri = dval;
// 实际赋值过程如下,产生了一个中间变量
double dval = 3.14;
const int temp = dval;
const int &rt = temp;

上述代码都可以编译通过,看代码块2,在将dval的值赋值到ri上的时候,会生成中间变量,这个变量是一个临时值,也就是一个右值,这时想要创建引用,就必须使用右值引用来接收,代码块1编译通过,证明了这一点。

int &b = dval;会编译错误,不能使用左值引用来接受,是因为C++ 标准规定,非const左值引用不能绑定到临时对象上。这种设计的初衷是为了防止程序员意外修改转换后临时对象的值,或者在引用一个临时对象时产生意外的副作用。

为什么可以用const int temp来接收呢,因为临时量,也就是字面量,或者说右值,可以用来初始化变量,也可以用来初始化常量,int aa = dval;使用字面量初始化一个变量,编译通过。

为什么const int &rt = temp;就可以使用左值引用来接收,因为const int temp = dval;,已经将右值固化,有了固定的内存地址,此时temp是左值。两个步骤都必须存在const的原因就是为了延长临时对象的生命周期,安全绑定,避免意外转换造成引用为空。

引用的底层是常量指针,指针本身不可以修改,指向的对象可以修改。常量引用就可以理解为指向常量的常量指针,指针本身以及指向的对象都不可以修改。