这也算是一个老生常谈的问题,写这个其实就是想趁着暑假把博客丰富一下。

咱随便在谷哥、度娘、病软引擎上搜搜都可以得到各种关于引用的解释,无非就是“引用不同于指针,引用是一个变量的别名”“使用引用就是使用变量本身”“”等等这些,于是大量的概念轰炸下,“引用不占用空间”这一言论貌似也是到处都有,流传甚广,几近泛滥,已经有淹没真想之势。于是本着追逐真理之精神,把引用究竟占不占空间这事儿解释清楚,至于引用与指针是不是不同的东西,这一哲学问题见仁见智,咱们就不去探究,真想搞清楚还是得问C++的爸爸。

真要搞清楚,还得从代码本身出发。

int main()
{
int a=10;
int* b=&a;
a=30;
*b=20;
}

先看看这段代码有什么意义?是不是觉得没有什么意义?嗯,确实没什么意义,从表面上也完全看不出什么来,当然了,如果您看出什么来了,那您一定要当什么都没看出来!

好了,要想知道这段代码做了什么,还得从汇编看起,毕竟从底层看起能都尽量多地绕过编译器,展示其真实行为,不失为一个学习基本概念的好办法。因为我用的是linux平台,所以我比较倾向于用AT&T汇编展示,如果您不熟悉,完全没关系,赶紧关掉网页,麻溜走人!。。。。。英雄留步,我这儿跟你开个玩笑活跃一下气氛,诶,诶,那位爷,能别抄起凳子么?

subl    $16, %esp    //分配空间
call ___main
movl $10, 8(%esp) //把10存入变量a代表的空间
leal 8(%esp), %eax //将变量a的地址存入寄存器eax
movl %eax, 12(%esp) //将变量a的地址存入另一块儿地址,这里即指针b
movl $30, 8(%esp) //将30赋值给变量a
movl 12(%esp), %eax //将变量a的地址赋值给寄存器eax
movl $20, (%eax) //将20赋值给寄存器eax的值所代表的地址处,

通过注释(应该还算清晰吧),可以完整对应上面那段代码的行为,这里可以真切地从肌肤与体位上感受到其行为的确定性。可以看到,一切都在我们的掌控之中。

下面对代码进行一点小修改:

int main()
{
int a=10;
int& b=a;
a=30;
b=20;
}

经过对比,可以看到,仅仅是将指针换成了引用,嗯,从语义上看,其行为貌似发现了一些变化,但是在内部发生了什么呢?您请往下走:

subl    $16, %esp
call ___main
movl $10, 8(%esp)
leal 8(%esp), %eax
movl %eax, 12(%esp)
movl $30, 8(%esp)
movl 12(%esp), %eax
movl $20, (%eax)

なに!代码发生了什么变化?您看出变化来了吗?如果您看出来了,出门儿右拐大药房滴眼液来两滴。

可以看到汇编层面上,其行为没有任何变化,与指针是一模一样的,咱们就此打住,不用多想,指针要占用4字节的空间,您引用既然和指针是同样的东西,凭什么不占?嗯,其实就这么点事儿。

C++中的引用到底是什么的更多相关文章

  1. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  2. 【Java面试题】15 String s="Hello"; s=s+“world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?String与StringBuffer的超详细讲解!!!!!

    1.Java中哪些类是不能被继承的? 不能被继承的是那些用final关键字修饰的类.一般比较基本的类型或防止扩展类无意间破坏原来方法的实现的类型都应该是final的,在java中,System,Str ...

  3. linux中的selinux到底是什么

    一文彻底明白linux中的selinux到底是什么 2018年06月29日 14:17:30 yanjun821126 阅读数 58877 标签: SElinux 更多 个人分类: Linux   一 ...

  4. Java中的String到底占用多大的内存空间?你所了解的可能都是错误的!!

    写在前面 最近小伙伴加群时,我总是问一个问题:Java中的String类占用多大的内存空间?很多小伙伴的回答着实让我哭笑不得,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有说不知道 ...

  5. Java中的线程到底有哪些安全策略

    摘要:Java中的线程到底有哪些安全策略呢?本文就为你彻底分析下! 本文分享自华为云社区<[高并发]线程安全策略>,作者:冰 河 . 一.不可变对象 不可变对象需要满足的条件 (1)对象创 ...

  6. php中关于引用(&)详解

    php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...

  7. 浅谈Java中的引用

    在Java语言中,引用是指,某一个数据,代表的是另外一块内存的的起始地址,那么我们就称这个数据为引用. 在JVM中,GC回收的大致准则,是认定如果不能从根节点,根据引用的不断传递,最终指向到一块内存区 ...

  8. error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用

    MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 Debug ...

  9. c++中的引用与指针的区别

    http://blog.csdn.net/lyd_253261362/article/details/4323691 c++中的引用与指针的区别 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存 ...

随机推荐

  1. 利用java生成带有干扰线的网页验证码图片

    package imageCreate; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import j ...

  2. iOS断点及打印日志

    首先,最简单的断点就是在Xcode项目文件中任意一行行号那点一下,就是加了一个断点 再次点击会变成浅蓝色,表示disable掉了 disable掉的断点不会起作用,但会在左上角蓝色的标签那留下记录,这 ...

  3. Hql参数占位符使用(转+整理)

    在Hibernate 4版本中,对于Hql有一点点改变,如果你还是按照以前的方式去编写HQL Query query = sessionFactory.openSession().createQuer ...

  4. AfxEnableControlContainer()

    1)OLE(Object Linking and Embedding,对象连接与嵌入).是一种面向对象的技术,利用OLE可开发可重复使用的软件组件(COM). 2)ActiveX 控件是基于组件对象模 ...

  5. Android onSaveInstanceState()

    我们知道,由于手机的内存问题,很容易造成切换activity之后上一个activity被回收的情况,虽然我们按下back按键的时候,还是能够回到上一个activity,但是此时我们并不是执行的onRe ...

  6. 5.7.2.2 min()和max()方法

    Math对象还包含许多方法,用于辅助完成简单和复杂的数学计算. 其中,min()和max()方法用于确定一组数值中的最小值和最大值.这两个方法都可以接受任意多个数值参数,如下例子: var max = ...

  7. mysql性能优化学习笔记(1)优化目的、方向及数据库准备

    前言: 最近参加面试,问到了很多关于mysql的优化方面的问题,回答的不是很好,也是因为原先做的项目流量不是很大,所以对mysql优化不是太了解,所以趁着周末,恶补一下. 本文来源于慕课网sqlerc ...

  8. Python学习笔记(一)基础

    学习资料 跟着廖雪峰的Python教程学习Python,大家可以去官方网站查看学习教程.使用的Python版本为3.0.x,解释器为CPython.本系列博客为学习笔记,记录跟随廖老师所学知识,同时会 ...

  9. [转]用Gson来解析Json数据

    转自太阳尚远的博客:http://blog.yeqianfeng.me/2016/03/02/use_gson_to_parse_json/ 在我们实际开发中像Json和XML这两种格式的数据是最常见 ...

  10. NetworkManager配置网络——Red Hat 7 && CGSL V5

      NetworkManager服务管理网络方便在哪? 很重要的一点是:一个设备可以对应多个配置文件,但是同一时间只能有一个配置文件生效,这对于频率切换网络环境是非常方便的,不用再跑那个目录下去改配置 ...