1.概念
引用不是新定义一个变量,而是 相当于给变量起了一个别名,编译器不会为引用变量开辟内存空间,而是和所引用的变量共用同一个命名空间.当改变这个变量的时候,它所引用的变量的内容也会随之改变.
举个例子:
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;
cout << a << endl;
cout << b << endl;
b = 20;
cout << a << endl;
cout << b << endl;
return 0;
}
我们定义一个变量a = 10 ; 再给a取一个别名 b ,此时b就是对a的引用,因此我们改变b的值a也会发生改变,运行结果如下:
就好像张三的小明叫阿三,他妈妈问阿三吃饭了没有,阿三说吃了,那张三肯定也吃过饭了
这里需要注意一下,引用类型必须和引用实体是同种类型的
2. 引用的特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用了一个实体,就不能再引用其他实体
3.使用场景
1. 做参数
引用可以在函数传参的时候作为参数来使用,不仅可以达到和指针相同的效果,还能更加方便和理解,举个例子:
我们之前用c语言写一个交换函数的时候必须用指针才能改变实参,代码如下:
void swapc(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
在调用这个函数的时候我们必须传参数的地址才可以调用,而用了引用之后不仅代码简洁,也更加方便调用和理解:
#include<iostream>
using namespace std;
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 1;
int b = 2;
cout << a << endl << b << endl;
swap(a, b);
cout << a << endl << b << endl;
return 0;
}
引用可以达到和C语言指针相同的效果,运行结果如下:
2. 做返回值
如果一个函数的返回值是一个静态对象或者全局对象,那用引用做返回值相对来说就比较安全,若只是普通的函数用引用作为返回值,那就很可能因为函数销毁栈帧后建立新的栈帧而对所引用的值覆盖或更改,从而使引用返回的值变成野指针一样的存在.
因此,在使用传引用返回时,只有出了函数作用域对象还在的情况下才可以使用引用做返回值
并且,因为引用与指针的底层实现是相同的,因此引用的效率也是非常高的
3. 常引用
在引用的过程中,权限可以平移,可以缩小,但不能放大,例如:
在想要进行去权限放大的操作时,无法编译通过:
//权限不能放大
const int a = 0;
int& b = a; //编译报错
权限平移是可以的:
//权限平移
const int a = 1;
const int& b = a;
权限缩小:
//权限缩小
int a = 0;
const int& b = a;
4.引用和指针的区别
在语法上,引用是不开辟空间的,是以所引用的那片空间的别名,但是在底层的实现上是有空间的,因为引用是按照指针的方式来实现的.
指针和引用的不同点:
- 引用概念上定义一个变量的别名,指针存储一个变量的地址
- 引用在定义时必须初始化,而指针可以不用.
- 引用在初始化时引用了一个实体后,就不能再引用别的实体,而指针可以随意指向任何实体
- 引用不能为NULL,但指针可以
- 在sizeof中的含义不同,引用的结果时引用的类型的大小,而指针是指针地址空间所占大小32位为4,64位为8
- 引用自加是所引用实体加1,而指针是向后偏移一个指针的大小
- 有多级指针,但没有多级引用
- 访问实体的方式不同,指针需要解引用,引用不用
- 引用比指针使用起来更方便安全
引用完结❀❀❀