一、引用的基本概念
引用,并没有新创建一个变量,而是为一个已经存在的变量取了一个别名。引用和它所引用的变量共用同一块内存空间。
如图所示,我们为变量a起了一个别名为b,a和b共用同一块内存,修改b的值,a的值也随之一起改变。
二、引用和指针的区别?
定义一个指针和定义一个引用在汇编指令上是没有任何区别的。
如图所示,我们定义了一个a变量,定义了一个指向a的p指针,又定义了一个a的引用b,定义指针p和引用b的汇编指令一模一样。可以说引用是一种更安全的指针。
但是指针和引用仍有些许的区别:
-
指针本身是一个变量,存储的是一个地址值,指向另一个变量的内存位置;
引用本身不是一个独立的变量,它是一个已有变量的别名,不单独占用内存空间。
-
引用必须初始化,指针可以不初始化。指针可以为空(NULL或nullptr);
引用在定义后必须始终指向一个有效的对象,不能为空(NULL)。
-
引用只有一级引用,没有多级引用;
指针可以有一级指针,也可以有多级指针。
-
指针可以在程序执行的过程中改变它所指的对象;
引用一旦初始化绑定了一个对象,就不能再更改绑定到其他对象上。
数组的引用
格式如图所示:
如果用指针指向数组,由于指针自己本身是一个变量,我们在取指针大小的时候只会得到int类型的大小。
但使用引用来指向数组,新定义的引用变量和原本的数组变量指向同一块内存,就是原名与别名的关系,都可以得到原数组的大小。
三、左值引用和右值引用
左值:有内存,有名字,值可以修改
右值:没内存,没名字
int a = 10; // a是左值,10是右值
右值引用专门用来引用右值类型,指令上,可以自动产生临时量,然后直接引用临时量。
int &b = a; // 左值引用
int &&c = 20; // 右值引用
通过汇编代码我们可以看到,右值引用是先把右值通过一个临时变量存储到栈中,c是临时变量的引用。
const int &d = 20;
我们可以看到,通过const,同样可以达到和上面右值引用同样的效果,在汇编指令层面是一样的。区别在于,通过const声明的变量不能修改其引用的临时量内存,右值引用的方式可以修改其引用的临时量内存。
int &&c = 20; // 右值引用
c = 30; // 可以修改
int &e = c; // 一个右值引用变量,本身是一个左值
不能用右值引用引用一个左值!
int &&e = c; // 错误!不能生成临时量