- 引用:引用(&)与类型结合在一起,相当于给变量起别名,(引用不参与类型)底层以指针的方式来支持使用,在引用使用的地方,系统自带解引用的过程。
例:
int a=10;
int &b=a;//给变量a起别名叫b, 相当于int *b=&a;b也要开辟内存,因为底层实现时p是一个指针
b=20; //自带解引用 相当于*b=20;
引用的注意事项:
一.引用一定要初始化
例 :int &a; 错误
二.引用所引用的变量一定要能取地址
例;
int a=10;
int &b=a; //正确
int &c=10;// 错误,因为底层用指针支持,相当于 int *c=&10 ,这是错误的
三.引用不可改变
例:
#include<iostream>
using namespace std;
int main()
{
int a=10;
int b=20;
int &c=a;
c=b;
c=100;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
结果:

可见当改变c的指向后赋值,结果改变原指向的变量的数据
四.只能访问引用变量所引用的内存块的内容
因为所有用到引用的地方自带解引用
不能返回局部变量的地址或引用
例:
int &get()
{
int tmp=10;
return tmp;
}
int main()
{
int rt1=get();
cout<<rt1<<endl;
int &rt2=get();
cout<<rt2<<endl;
return 0;
}
结果:
发现结果符合我们的需求,如果在 int &rt2=get()函数后调用其他函数呢?
int &get()
{
int tmp=10;
return tmp;
}
void set()
{}
int main()
{
int rt1=get();
cout<<rt1<<endl;
int &rt2=get();
set();
cout<<rt2<<endl;
return 0;
}
我们只在 int &rt2=get()函数后调用set()函数,rt2的数值就发生了改变,可见返回局部变量的引用并不安全
因为函数返回了局部变量的地址, int &rt2=get()是给局部变量tmp的地址起别名rt2,在get()函数清栈后,我们又调用了set()函数,set()函数开栈时会初始化内存,将tmp的地址的内存数据修改,导致rt2访问数据时出错。
- const 和引用结合
常引用引用的变量可以不能取地址
例: int &a=10; //错误,
const int &a=10;//正确
因为先将10存放到临时量的内存中,常引用a引用临时量的内存单元
内置类型生成的临时量是常量(不能被修改)
例:
int a=10;
int *&p=&a; //错误,因为&a(a的地址)是常量
改为:int * const &p=&a;//正确
- const 和**(const 和指针结合主要防止间接访问修改常量内存块的值)
例:
int a=10;
int *p=&a;
const int**q=&p;//错误
因为第四行const int **q=p;
const 修饰的变量是**q ,类型是int
相当于a是常量
直接访问 a
间接访问 *p, **q, *(*q)==*p
const 修饰**q 可以通过*p或 *(*q)修改a的值
用const修饰*p或*q即可避免错误
即
int a=10;
int *p=&a;
int const *const*q=&p;
避免通过**q或*(*q)来间接访问修改常量内存块a的值,但可以通过p间接访问修改a的值(*p=20)
但const 定义在第三行,只看第三行和其以下的代码是否会修改常量内存块的值,并不关心const定义上方的变量间接访问是否会修改常量内存块的值。
或
int a=10;
const int *p=&a;
const int **q=&p;
避免通过*p,**q,*(*q)来间接访问修改常量内存块a的值
- const和形参结合
一.防止实参被修改
例:
int add(int *a,int *b)
{
*a=20;
return *a+*b;
}
int main()
{
int a=10;
int b=20;
cout<<add(&a,&b)<<endl;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
add()函数只是为了计算a+b的值,并不修改a和b的值,但函数中却修改了a的值,为了避免函数修改实参,给形参加上const
即 int add(const int*a,const int *b)
二.接收临时量
void swap(int &a,int &b)
{
int tmp=a;
a=b;
b=tmp;
}
int main()
{
int a=10;
int b=20;
swap(a,b);
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
上面代码中swap()函数实现了两个数的交换功能,但如果直接调用swap(10,20)时,程序崩溃,
因为int &a=10,int &b=20,不符合引用的规则(引用引用的变量一定要能取地址)
为了解决这个问题改为常引用,即 void swap(const int &a,const int &b)
当直接调用swap(10,20)时,先将20存放到临时量中,再将临时量的地址赋给b,再将10存放到临时量中,再将临时量的地址赋给a