目录

C++ 之引用(reference)

C++ 之引用(reference)

c++提供很多内存模型,甚至是很多地方可以存放对象(堆,栈,全局数据区),以及很多访问对象的方式,下文就介绍其中一种方式:引用。

本文只是记录了引用学习过程,参考资料:浙江大学授课

引用基本格式

引用的基本格式为 type & refname = name;,其中name必须是个实际的名字,且==必须经过初始化==,以下是三种访问数值的方式:

1
2
3
char c;//一个普通字符
char *p = &c;//利用指针访问字符;
char &r = c;//利用引用来访问字符

通过声明一个新的名字给存在的对象,并且通过引用的方式修改值

1
2
3
4
5
int x = 1;
int &y = x;
cout << "y = " << y; //输出y = 1;
y = 2;
cout << "x = "<< x;//输出x = 18;

引用规则

使用引用的规则,但定义引用类型时==必须被初始化==,初始化会建立一种绑定的关系

1
2
3
4
5
6
7
//声明
int x = 3;
int &y = x;
const int &z =x;
//作为函数参数
void f(int &x);
f(y);//当函数调用时初始化
  1. const表示通过z不得修改x,x可以做任意改变,其中绑定关系即使不存在const也是默认绑定(同const int *p = x有着异曲同工的作用,即表示x无法通过p这个指针被修改,)
  2. 关于void f(int &x);这里传入的是 x 的引用(说明此处传入就是 f(y) 里的 y ),也就是说如果调用f的函数,那么在函数内部可以直接更改y的值,而调用者无法通过调用方式来察觉值的变化
  3. 引用的绑定是无法在运行时被改变,这也就是和指针区别之一
  4. 引用的目标必须有一个临时存放的位置,若传入参数没有变量名,则会出现下述代码编译情况
1
2
void func(int &);
func(i*3);//警告或者报错

引用在函数中作用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
int* f(int* x) {
	(*x)++;
	return x;
}
int& g(int& x) {
	x++;
	return x;
}
int x;
int& h() {
	int q;
	//return q; //错误,无法返回一个地址值
	return x;//正确,x作为全局变量始终存在
}
int main() {
	int a = 0;
	f(&a);//a=1
	g(a);//a=2
	h() = 16;// == 16赋值给x的引用,所以x=16
}

指针对比引用

引用 指针
不能为空 可以设置为空
绑定导致无法指向新的地址 可以指向新的地址
需要依赖一个存在的值,只是一个变量的别名 可以独立于存在的对象
  1. 无法使引用出引用
1
2
3
4
int a;
int& b=a;
int& c=b;//错误,不存在引用的引用
int& c=a//正确,此时b,c皆为a的引用
  1. 没有指针可以被引用 int&* p是非法代码
  2. 指针可以去引用 void f(int*& p)是合法代码
  3. 没有数组的引用

引用的好处

其实相对于C++来说,引用保留了指针的好处,又减少了部分指针带来的安全隐患,更需要注意的时引用对于读取数据来说速度提升巨大,如果涉及到从高维数组读取大量数据时,在auto 后加入&来引用数据进行操作对于AC的时间来说有十分大的帮助。