request-free-img

C++引用底层原理揭秘:为什么引用也可以修改变量的值?

int x = 5;
int* p = &x;
*p = 10;

大家都知道C++中,可以通过指针来修改一个变量的值?

int x = 5;
int& ref = x;
ref = 10;

那为什么引用也可以修改一个变量的值?

指针指向的其实是一个内存地址,通过指针修改一个变量的值其实就是修改指定内存地址的值,这很好理解,是不是?

但是引用呢,它的底层原理又是什么?

今天这个视频,我就带着你弄清楚C++中引用的底层原理

不管你是新手还是老手,看完这个视频你一定会茅塞顿开,让你对C++的认识提升一个台阶。

汇编代码对比:指针与引用的实际实现

int main()
{
int a = 5;
int* p = &a;
*p = 10;
int b = 5;
int* p = &b;
*p = 10;
return 1;
}

我们这里有几行简单的C++代码

我们有一个int型的变量a,并尝试通过指针的方式修改变量a的值

然后还有一个int型的变量b,并尝试通过引用的方式修改变量b的值

现在我们在这里设置断点,运行程序,并进入到汇编模式

指针修改变量的汇编实现

int a = 5;
001849CF mov dword ptr [a],5
int* p = &a;
001849D6 lea eax,[a]
001849D9 mov dword ptr [p],eax
*p = 10;
001849DC mov eax,dword ptr [p]
001849DF mov dword ptr [eax],0Ah

引用修改变量的汇编实现

int b = 5;
001849E5 mov dword ptr [b],5
int&ref = b;
001849EC lea eax,[b]
001849EF mov dword ptr [ref],eax
ref = 10;
001849F2 mov eax,dword ptr [ref]
001849F5 mov dword ptr [eax],0Ah

为什么两者汇编代码完全一样?

咦,为什么采用指针方式和采用引用方式的汇编代码完全一样呢?

我们先看前边采用指针方式的汇编

这里将5赋值给a

然后取a的地址,并保存在eax中

再将eax的地址赋值给p

这一句将p指向的地址保持在eax中,然后再用mov指令将0A也就是10写入p指向的内存地址

这样就完成了通过指针来修改变量a的目的。

引用的底层真相

再看采用引用方式的汇编代码

这里将5赋值给b

然后取b的地址,并保存在eax中

然后将eax保存的内存地址赋值给ref。

ref是一个引用,也就是说在底层实现上,引用其实也是一个指针

我们接着看,接着它把ref的值保存到eax中,再使用mov指令将0A也就是10写入ref指向的内存地址

结论:引用的本质

到底,我们彻底明白了,

其实C++中的引用(int& ref = x)在底层是通过内存地址实现的。

它是编译器管理的地址操作

编译器将引用翻译为指向目标变量的地址,类似于指针(int* ptr = &x)

引用的“底层魔法”在于编译器的语法封装,让开发者用起来更安全、更直观,但底层仍是“指针的翻版”

关于引用的底层原理,现在你明白了吗?


更多问题探讨,请关注公众号:程序员角