C++中的引用&
文章目录
前言
大家先看一个笑话:
我们周末的时候常常和同事一起打麻将。有一天,可能是从上午打到晚上吧,脑子里都是麻将了。有一个人就对一个姓洪的同事说:“红中阿……”我们全晕了!自此,那个人多了个外号,叫红中。
这个笑话跟引用有什么关系呢?和引用很相似就是起外号或者说起别名。
一、引用的定义
引用(reference)就是C++对C语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:类型标识符 &引用名=目标变量名;
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*
1.1对单变量的引用
#include<iostream>
using namespace std;
void main() {
int a = 10;
int& ra = a;//<====定义引用类型
printf("%p\n", &a);
printf("%p\n", &ra);
}
这里的声明的ra变量就是对a变量的引用,ra是变量a的一个别名,那么对引用ra的操作就是对变量a的操作。
1.取别名只是在原有空间上做一个命名,所以在原有空间上不会做任何的覆盖。
2.操作原名和别名都是可以的。
3.引用不会开辟新的空间。
如上图的运行结果,两个变量名的空间地址相同,实际上就是同一个地址空间重新取了一个名字,所以说对a还ra操作都是对同一个空间操作。这就是姓洪的同事和红中之间的关系,大家都知道说的是一个人。
同时要注意:引用类型必须和引用实体是同种类型的
int main(){
int a=10;
char& b=a;
}
1.2引用的特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体
1.3其他的引用
除了上面的单变量引用之外我们再看看其他的引用
1.3.1指针的引用
#include<iostream>
using namespace std;
void main() {
int a = 10;
int* p = &a;
int*& q = p;//<====指针的引用
}
q这个指针就是p这个指针的别名
1.3.2.数组的引用
#include<iostream>
using namespace std;
void main() {
int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };
int br[10] = ar;
}
注意:这种方式是错误的数组不允许整体的赋值
#include<iostream>
using namespace std;
void main() {
int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };//数组的引用
int(&br)[10] = ar;
}
1.4引用使用的场景
1.4.1做参数
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
1.4.2做返回值
int& Count()
{
static int n = 0;
n++;
// ...
return n;
}
不能返回局部变量的引用。局部变量在函数返回后会被销毁,因此被返回的引用的就成了“无指针”引用,程序就会进入未知状态。
二.常引用
采用const声明的引用,常引用指向的对象不能被修改,函数中使用常引用
作为参数,其目的是保护实参不被修改。
声明常引用的方式如下:
const 类型说明符 &引用名;
cpp
void main() {
int a = 10;
int &b = a;
const int& c = a;
a = 100;
b = 1000;
cout << c << endl;
}
通过这种方式的声明的引用,不能通过引用对目标变量的值进行修改,从而使得引用的目标成为const,达到引用的安全性。
三.引用和指针的区别
3.1.1相同点
都是地址的概念,指针指向一块内存,内容所指的是内存的地址;引用是某块内存的别名,没有独立空间,和其引用实体共用同一块空间。
int main()
{
int a = 10;
int& ra = a;
cout<<"&a = "<<&a<<endl;
cout<<"&ra = "<<&ra<<endl;
return 0;
}
引用实际上是按照指针的方式实现的
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
3.1.2区别
1.指针是一个实体,而引用仅是个别名。
2.引用使用时无需解引用(*),指针需要解引用。
3.引用在定义时必须初始化,指针没有要求。
4. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
5. 没有NULL引用,但有NULL指针。
6. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。
7. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
8. 有多级指针,但是没有多级引用。
9. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
10. 引用比指针使用起来相对更安全。