C++中的引用到底是什么
这也算是一个老生常谈的问题,写这个其实就是想趁着暑假把博客丰富一下。
咱随便在谷哥、度娘、病软引擎上搜搜都可以得到各种关于引用的解释,无非就是“引用不同于指针,引用是一个变量的别名”“使用引用就是使用变量本身”“”等等这些,于是大量的概念轰炸下,“引用不占用空间”这一言论貌似也是到处都有,流传甚广,几近泛滥,已经有淹没真想之势。于是本着追逐真理之精神,把引用究竟占不占空间这事儿解释清楚,至于引用与指针是不是不同的东西,这一哲学问题见仁见智,咱们就不去探究,真想搞清楚还是得问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++中的引用到底是什么的更多相关文章
- 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感
关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...
- 【Java面试题】15 String s="Hello"; s=s+“world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?String与StringBuffer的超详细讲解!!!!!
1.Java中哪些类是不能被继承的? 不能被继承的是那些用final关键字修饰的类.一般比较基本的类型或防止扩展类无意间破坏原来方法的实现的类型都应该是final的,在java中,System,Str ...
- linux中的selinux到底是什么
一文彻底明白linux中的selinux到底是什么 2018年06月29日 14:17:30 yanjun821126 阅读数 58877 标签: SElinux 更多 个人分类: Linux 一 ...
- Java中的String到底占用多大的内存空间?你所了解的可能都是错误的!!
写在前面 最近小伙伴加群时,我总是问一个问题:Java中的String类占用多大的内存空间?很多小伙伴的回答着实让我哭笑不得,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有说不知道 ...
- Java中的线程到底有哪些安全策略
摘要:Java中的线程到底有哪些安全策略呢?本文就为你彻底分析下! 本文分享自华为云社区<[高并发]线程安全策略>,作者:冰 河 . 一.不可变对象 不可变对象需要满足的条件 (1)对象创 ...
- php中关于引用(&)详解
php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...
- 浅谈Java中的引用
在Java语言中,引用是指,某一个数据,代表的是另外一块内存的的起始地址,那么我们就称这个数据为引用. 在JVM中,GC回收的大致准则,是认定如果不能从根节点,根据引用的不断传递,最终指向到一块内存区 ...
- error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 Debug ...
- c++中的引用与指针的区别
http://blog.csdn.net/lyd_253261362/article/details/4323691 c++中的引用与指针的区别 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存 ...
随机推荐
- Oracle利用过程procedure块实现银行转账
-- create table account( id ) not null, name ), ,2), constraint a_pk primary key(id) ); --历史表 select ...
- Hadoop学习笔记——入门指令操作
假设Hadoop的安装目录HADOOP_HOME为/home/admin/hadoop. 启动与关闭启动HADOOP1. 进入HADOOP_HOME目录. 2. 执行sh bin/start-all. ...
- DataTable转换为LIST
public List<string[]> SetList(DataTable dt) { List<string[]> list = ne ...
- UI事件之unload、resize和scroll
unload事件 当页面卸载或用户从当前页面换到其他页面上时,会在window上触发unload事件.根据DOM2级规范规定,unload应该在body上触发,但所有浏览器都实现了在window上触发 ...
- Inno setup卸载前退出进程、删除文件夹
[Code]function InitializeUninstall(): Boolean; var MainRun: HWND; var MVRun:HWND; begin// FindWindow ...
- 编译安装apache2.4
一.编译安装apache2.4Apache官方说:与Apache 2.2.x相比,Apache 2.4.x提供了很多性能方面的提升,包括支持更大流量.更好地支持云计算.利用更少的内存处理更多的并发等. ...
- Javascript 拖拽雏形中的一些问题——逐行分析代码,让你轻松了解拖拽的原理
今天我们就来解决上一次拖拽雏形中的一些问题.下面看看有哪些问题? 附上上期的Javascript代码,方便大家查看问题. <script type="text/javascript&q ...
- 嵌入式程序员应知道的0x10个基本问题
来源:网络 嵌入式程序员应知道的0x10个基本问题 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 ...
- 修改vim默认tab为4个空格与显示行号
添加一个.vimrc配置文件即可. 在home目录下 vim .vimrc # 添加如下内容 set ts=4 set expandtab set nu 然后再次用vim打开任意文件,就看见效果啦!
- Database.SetInitializer的几种参数
一:数据库不存在时重新创建数据库 Database.SetInitializer<testContext>(new CreateDatabaseIfNotExists<testCon ...