引用的概念
引用为对象起了另外一个名字,相当于为对象取了一个别名,在对引用进行初始化时,相当于把引用和它的初始值绑定在一起,两者共同使用同一块内存空间,因此对引用的操作是作用在初始变量之上的;
引用的定义
在定义初始变量之后,使用与初始变量同类型的定义+&+引用声明符=初始变量;
int val = 9;
int& refval = val;
引用的特性
-
引用在定义的时候必须初始化,也就是在取别名必须要有一个主人;
-
一个初始变量可以拥有多个引用;
-
同一个引用只能有一个对象;
-
引用本身并非一个对象,因此引用无法嵌套,不能定义引用的引用;
引用的使用
做输出型参数
当我们在进行函数调用时,往往会进行传值操作,而利用引用传参,提高传参效率并且会简化代码逻辑,能够对该空间进行直接的操作,不会受函数销毁的影响:
void swap(int& NUM1, int& NUM2)
{
int tmp = NUM1;
NUM1 = NUM2;
NUM2 = tmp;
}
做返回值
首先这里我们先区分一下传值返回和传引用返回的过程:
传值返回:将返回的值进行拷贝给寄存器或者是压一块空间创建临时变量进行返回;
传引用返回:函数定义形如:
int& func()
{
//函数主体;
return n;
}
返回的是n的引用,返回之后这片空间被销毁,内部的变量状态未知,此时返回的数值可能是随机值也有可能是原本返回的值,有点类似于玩野指针,相对传值或者传地址来说比较危险,看似来说仿佛不是很好用,但是如果是一个静态的对象,抑或是说出了函数域之后变量还存在仍旧可以使用,并且在一些特定的场景来说是非常方便的:例如当我们在设计线性表的寻找数值、修改数值这两个函数操作时,如果不用引用,往往会设计两个函数进行操作,而使用引用作为寻找数值的返回时,可直接在外部修改次节点数值,非常的方便。
常引用
常引用即为对常性变量的引用,形如const int& b=a。
对于用const限定定义的变量,不能直接进行引用,因为此时相当于把权限放大了,所以在引用时也要const,也就是常引用,相当于权限平移:
const int b=8;
const int&x =b;
普通定义时,在引用时用const限定可以,相当于权限的缩小,原定义的值改变,const的引用也会改变:
int x=9;
const int& y=x;
特别的,当类型转换时抑或是传值返回时是一个拷贝,会将原类型的数值给上一个现类型的临时变量,而临时变量具有const的特性,所以你在引用时是一个权限放大或者是对一个常值的引用,因此此时引用失败,而在引用时加const则为权限平移,并且会延长其生命周期
引用和指针的区别
首先引用在语法层面上虽然是一个别名,没有独立空间,但在其底层实现上是有空间的,其按照指针方式来实现,但是两者具有如下的区别:
1.引用概念上定义一个变量的别名,指针存储一个变量地址;
2.引用在定义时需要初始化,而指针不需要;
3.引用有且仅有一个实体,且不能改变,而指针可以;
4.引用没有多级引用,而指针具有多级指针。