C++引用(Reference)详解——从入门到理解本质
目录
一、什么是引用?
在 C++ 中,引用(Reference)并不是新定义一个变量,而是:
给已经存在的变量取一个“别名”。
也就是说:
-
引用和原变量使用的是同一块内存空间
-
修改引用,其实就是修改原变量
-
编译器不会额外开辟空间
生活中的理解
例如:
-
李逵 → “铁牛”
-
李逵 → “黑旋风”
虽然名字不同,但本质上还是同一个人。
引用也是一样:
int a = 10;
int& b = a;
这里:
b
只是:
a
的另一个名字。
二、引用的定义方式
基本语法
类型& 引用名 = 引用对象;
例如:
int a = 0;
int& b = a;
三、引用的本质理解
来看下面代码:
#include<iostream>
using namespace std;
int main()
{
int a = 0;
int& b = a;
int& c = a;
int& d = b;
++d;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
}
运行结果特点
会发现:
a、b、c、d 的地址完全相同
说明:
引用本质上就是同一个变量的多个名字。
四、引用的特性
1. 引用必须初始化
引用在定义时必须绑定对象。
错误写法
int& ra;
因为引用必须明确“引用谁”。
✔ 正确写法
int a = 10;
int& ra = a;
2. 一个变量可以有多个引用
int a = 10;
int& b = a;
int& c = a;
int& d = a;
这些都是:
a
的别名。
3. 引用一旦绑定,不能修改指向
例如:
int a = 10;
int& b = a;
int c = 20;
b = c;
很多人以为:
b 改为引用 c
实际上并不是。
真正发生的是
a = c;
即:
把 c 的值赋给 a。
原因
因为:
C++引用不能重新绑定对象。
五、引用的核心用途
引用最常见的用途:
-
引用传参
-
引用返回值
六、引用传参
传统交换函数(C语言)
C语言通常需要:
Swap(int* px, int* py)
需要传地址。
C++引用版本
void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
调用方式
int x = 0;
int y = 1;
Swap(x, y);
优势
相比指针:
✔ 调用更简单
✔ 不需要取地址
✔ 可读性更高
✔ 更接近普通变量使用方式
七、引用在数据结构中的使用
很多数据结构教材会大量使用引用。
目的:
替代复杂指针传参,简化代码。
八、引用修改结构体
例如栈初始化:
void STInit(ST& rs, int n = 4)
这里:
rs
实际上就是:
st
本身。
好处
函数内部修改:
rs.top
实际上就是修改:
st.top
九、引用作为返回值
来看代码:
int& STTop(ST& rs)
{
return rs.a[rs.top];
}
为什么返回引用?
因为:
STTop(st1) += 10;
需要直接修改栈顶元素。
如果不返回引用
返回的是临时值:
修改不了原数据
返回引用后
相当于:
直接返回原对象本身
因此可以直接修改。
十、引用替代二级指针
链表中经常需要:
LTNode**
很多人觉得很复杂。
使用引用后
void ListPushBack(PNode& phead, int x)
这里:
PNode&
其实就是:
LTNode*&
即:
“指针变量的引用”
好处
这样就不需要:
二级指针
代码更容易理解。
十一、const引用
1. const对象必须用const引用
例如:
const int a = 10;
错误写法
int& ra = a;
因为:
普通引用会导致权限放大。
✔ 正确写法
const int& ra = a;
2. const引用可以引用普通对象
int b = 20;
const int& rb = b;
这是允许的。
原因
因为:
权限可以缩小,但不能放大。
注:虽然rb不能修改,但是b可以修改,rb权限变了不代表b的权限变了
十二、临时对象与const引用
来看代码:
const int& rb = a * 3;
为什么必须加const?
因为:
a * 3
会产生:
临时对象
而 C++规定:
临时对象具有常性。
所以只能:
const int&
来引用。
十三、什么是临时对象?
临时对象:
编译器为了保存表达式结果而临时创建的匿名对象。
例如:
a * 3
结果不会立刻消失,而是暂时保存。
这个保存结果的对象就是:
临时对象
注:常见的临时对象有:表达式,隐式类型转换(如将一个int变量赋值给一个double变量)
十四、引用和指针的区别
相同点
-
都能间接访问对象
-
都能修改对象
不同点
引用
✔ 必须初始化
✔ 不能改变绑定
✔ 使用更方便
指针
✔ 可以为空
✔ 可以改变指向
✔ 更灵活
更多推荐

所有评论(0)