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

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

    其实eclipse安装插件更方便的方法就是直接扔到eclipse目录下的dropins文件夹,但如果插件比较多或者大的话,会让eclipse变得臃肿.下面介绍的用link方式可以避免这样的问题. 用l ...

  2. Spring随笔 - 事务传播行为

    Spring定义了7种不同的事务传播行为: PROPAGATION_MANDATORY:表示该方法必须在事务中运行.如果当前事务不存在,则会抛出一个异常. PROPAGATION_NESTED:表示如 ...

  3. PDO的事物处理机制

    Mysql的事务处理: 1.MySQL目前只有InnoDB 和BDB两个数据表类型才支持事务. 2.在默认条件下,MySQL是以自动提交(autocommit)模式运行的,这就意味着所执行的每一个语句 ...

  4. Python学习路径和个人增值(整合版)

    PS:内容来源于网络 一.简介         Python是一种面向对象.直译式计算机程序设计语言,由Guido van Rossum于1989年底发明.由于他简单.易学.免费开源.可移植性.可扩展 ...

  5. TCP粘包拆包问题

    阿π 专注于网络协议,系统底层,服务器软件 C++博客 | 首页 | 发新随笔 | 发新文章 | | | 管理 Socket粘包问题 这两天看csdn有一些关于socket粘包,socket缓冲区设置 ...

  6. OleVariant的本质

    OleVariant的本质 OleVariant,COM的一种数据类型.MIDAS基于COM之上构建的,自然使用OleVariant作为数据序列格式. 延续到现在最新的DATASNAP仍然支持它. T ...

  7. VC维的物理意义

    vc约等于可调节参数的个数 来自为知笔记(Wiz)

  8. openStack CI(Continuous interaction)/CD(Continuous delivery) Gerrit/Jenkins安装及集成,插件配置

    preFace: CI/CD practice part contains the following action items and fields of expertise: Gerrit ins ...

  9. 适合入门自学服装裁剪滴书(更新ing)

    [♣]适合入门自学服装裁剪滴书(更新ing) [♣]适合入门自学服装裁剪滴书(更新ing) 适合入门自学服装裁剪滴书(更新ing) 来自: 裁缝阿普(不为良匠,便为良医.) 2014-04-06 23 ...

  10. ubuntu 设置网卡为混杂模式 以及网络配置命令

    1. ifconfig eth0 promisc 设置eth0为混杂模式. ifconfig eth0 -promisc 取消它的混杂模式 botnet@botnet-virtual-machine: ...