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++中的引用到底是什么

时间: 2024-12-20 10:37:25

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

无法解析的外部符号 _ ,该符号在函数 " __main中被引用 && This function or variable may be unsafe.

加上winsock2的运行库看看吧,一般不用加的啊 #pragma comment(lib,"Ws2_32.lib") 应该就没有问题了吧^_^ 以下为转载 http://blog.chinaunix.net/uid-20672257-id-2955771.html 1.将过去的工程用VS2010打开的时候.你有可能会遇到一大堆的警告:warning C4996. 比如:warning C4996: 'sprintf': This function or variable may be

Android Studio如何查看资源或者函数在哪些类中被引用

许多人在做完Keymap匹配到Eclispe快捷键后,发现查看资源或者函数在哪些地方被引用的快捷键"Ctrl+Shift+G"不灵 了,你选中某个函数后,使用这个快捷键,发现只会光标跳到该类中引用这个函数的地方.原因是啥呢? 首先这里简单分析下,选择Keymap后IDE所做的工作及选择后发生快捷键失效原因,Android Studio设置KeyMap到 Eclipse,是进行了一个快捷键的映射操作,但是Android Studio本身的快捷键数量和Eclipse是不一样的,比如Andr

请注意,java中没有引用传递-----转载

1 说明:本文的适用对象为java初学者.如果有读者发现文章中有叙述不妥之处,请指正. 2 3 今天在论坛上有人提了一个关于java中调用函数时有没有引用传递的问题,可谓是吵的不可开交.有人说java只有值传递,也有人说java既有值传递也有引用传递,那么java中到底有没有引用传递呢,下面我来分析一下. 4 5 一.首先来明确一下"值传递"和"引用传递的"区别 6 7 值传递:是对所传递参数进行一次副本拷贝,对参数的修改只是对副本的修改,函数调用结束,副本丢弃,原

请注意:java中没有引用传递

说明:本文的适用对象为java初学者.如果有读者发现文章中有叙述不妥之处,请指正. 今天在论坛上有人提了一个关于java中调用函数时有没有引用传递的问题,可谓是吵的不可开交.有人说java只有值传递,也有人说java既有值传递也有引用传递,那么java中到底有没有引用传递呢,下面我来分析一下. 一.首先来明确一下"值传递"和"引用传递的"区别 值传递:是对所传递参数进行一次副本拷贝,对参数的修改只是对副本的修改,函数调用结束,副本丢弃,原来的变量不变(即实参不变)引

linux中的selinux到底是什么

一文彻底明白linux中的selinux到底是什么 2018年06月29日 14:17:30 yanjun821126 阅读数 58877 标签: SElinux 更多 个人分类: Linux 一.前言 安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统. SELinux 主要由美国国家安全局开发.2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块. SELinux

C++中的引用

引用就是某个目标变量的别名,对引用的操作与对变量的直接操作效果完全相同. 引用的声明方法:类型标识符 &引用名=目标变量名: 如下:定义引用ra,它是变量a的引用,即别名. int a; int &ra=a; 1)  声明一个引用,必须进行初始化. 2)引用声明完毕后,相当于目标变量有两个名称即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名. 3)引用本身不是一种数据类型,因此引用本身不占存储单元,系统也不会给引用分配存储单元. 4)不能建立数组的引用.因为数组是一个由若干个

错误 1 error LNK2019: 无法解析的外部符号 __imp__pthread_create,该符号在函数 _main 中被引用 解决方法

晚上花几分钟在windows下测了下pthread的用法,出现错误 1 error LNK2019: 无法解析的外部符号 __imp__pthread_create,该符号在函数 _main 中被引用 经网上搜,反正都没解决,其中一个说引入#pragma comment(lib, "pthreadVC2.lib")后解决,但笔者遇到的不是这个原因,而是版本问题.可参考http://www.cnblogs.com/zhjh256/p/6364777.html解决.

WPF中静态引用资源与动态引用资源的区别

WPF中静态引用资源与动态引用资源的区别 WPF中引用资源分为静态引用与动态引用,两者的区别在哪里呢?我们通过一个小的例子来理解. 点击“Update”按钮,第2个按钮的文字会变成“更上一层楼”,而第1个按钮的文字没有变化. 原因是第1个按钮文字用的是静态引用资源,而第2个按钮文字用的是动态引用资源. 前台代码: <Window x:Class="PersonalLearning.StaticDynamicResourceDemo"        xmlns="http

[Perl系列—] 2. Perl 中的引用用法

Perl 中的引用,为什么要使用引用? 对于熟悉C语言的开发者来说, 指针这个概念一定不陌生. Perl 的引用就是指针,可以指向变量.数组.哈希表甚至子程序. Perl5中的两种Perl引用类型为硬Perl引用和符号Perl引用.符号Perl引用含有变量的名字,它对运行时创建变量名并定位很有用,基本上,符号Perl引用就象文件名或UNIX系统中的软链接.而硬Perl引用则象文件系统中的硬链接. Perl4只允许符号Perl引用,给使用造成一些困难.例如,只允许通过名字对包的符号名哈希表(名为_