C++"引用"本质探究——穷极一生,终成替身?

C++"引用"本质探究——穷极一生,终成替身?

《C++ Primer 第五版》中如此描述“引用”:
“引用并非对象,它只是为一个已经存在的对象起的另外一个名字”
“引用没有实际地址”
那么,何为对象。
《C++ Primer 第五版》中如此定义“对象”:
“对象是指一块能储存数据并具有某种类型的内存空间”

甚至,有些说法是,引用不占内存空间。可是,引用,它真就这么卑微吗?
"Talk is Cheap. Show me the Code".
请看如下代码:

	int i = 5;			//声明int型变量i,初始化为5;
	int& r = i;			//声明int型引用r,与i绑定;
	int* p = &i;		//声明int型指针p,指向i;
	printf("%d\n", r);
	printf("%d\n", *p);

请看VS2019反汇编结果:
先看声明部分:

	int& r = i;
lea		eax,[i]  
mov		dword ptr [r],eax  
	int* p = &i;
lea		eax,[i]  
mov		dword ptr [p],eax  

前两句:将i的地址存入eax寄存器,再将eax寄存器的值存入r的内存;
后两句:将i的地址存入eax寄存器,再将eax寄存器的值存入p的内存;
也就是说,r和p的内存都保存了i的内存地址,即[ i ]
两者如出一辙,引用与指针声明部分的底层实现几乎一致

觉得蹊跷吗?那我们再来看输出部分的汇编代码:

	printf("%d\n", r);
 mov	eax,dword ptr [r]  
 mov	ecx,dword ptr [eax]  
 push	ecx  
 ...
	printf("%d\n", *p);
 mov	eax,dword ptr [p]  
 mov	ecx,dword ptr [eax]  
 push	ecx  
 ...

//省略部分printf函数调用汇编
//汇编小知识:[ ]内的是地址,ptr代表取内存上的值,相当于解引用
前两句:将r地址上的值(也就是i的地址)存入eax寄存器,再将eax寄存器的值(i的地址)所指的值(i的值)存入ecx寄存器,然后push压栈,供后续输出;
这难道不就是指针的工作方式吗?
有趣吗?这脸打得啪啪响,那三句话依旧历历在目,“引用并非对象,没有实际内存地址,不占内存”

子路曰∶“卫君待子而为政,子将奚先?” 子曰∶“必也正名乎!”

我想为"引用"正名。
引用的本质是指针,是一块保存了变量地址的内存空间,实际使用上r与*p并无差异,可以理解为编译器帮助你做了这些看似多余的“解引用”操作,然后冠冕堂皇地瞒上欺下,告诉程序员,别名而已,别名而已。

有一说一:
有了引用限制了指针的胡作非为,使得使用上更简便,安全。

话虽如此,我依旧不希望身为一个程序员,却被欺瞒,理解引用的本质对C++的学习、使用大有裨益。
//为什么书本、老师都不说实话呢?
最后一句,“实践是检验真理的唯一标准”信书本、信权威,不如相信CPU运算的结果

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值