引用和指针有什么区别?引用在进程中是否会分配内存?

C++ primer中说: 引用就是对象的另一个名字。
C++ primer中说: 指针用于指向对象,保存的是另一个对象的地址。 从字面意义上,感觉引用并没有分配内存,而指针是分配了内存的,于是写了个小程序进行测试。 int main()
{
long val = ;
long &r_val = val;
const long &const_r_val = val;
const long &const_r_tmp = ;
long *p_val = &val;
printf("val address: 0x%lx\n", &val);
printf("r_val address: 0x%lx\n", &r_val);
printf("const_r_val address: 0x%lx\n", &const_r_val);
printf("const_r_tmp address: 0x%lx\n", &const_r_tmp);
printf("p_val address: 0x%lx\n", &p_val);
void *tmp;
tmp = &r_val;
const void *const_tmp;
const_tmp = &const_r_tmp;
tmp = &p_val;
return ;
}
采用g++编译得到如下结果: val address: 0x7fff7377ee48
r_val address: 0x7fff7377ee48
const_r_val address: 0x7fff7377ee48
const_r_tmp address: 0x7fff7377ee50
p_val address: 0x7fff7377ee40
可以看出对引用取地址(&)跟变量取地址(&)都是得到同一个地址值,而对指针取地址(&)得到的是另外一个地址,好像引用真的没有分配内存,这是真的吗???? 其实上不然,从C++语义上说,引用就是对象的另一个名字,并没有具体的指定另一个名字的具体实现,根据编译器的不同,引用的实现也不一样。 我们通过objdump –d a.out进行反编译可知: long val = ;
movq $0x1,0xffffffffffffffe8(%rbp)//将立即数1复制给val所在的内存
long &r_val = val;
lea 0xffffffffffffffe8(%rbp),%rax//将val所在的内存地址赋值给rax
mov %rax,0xfffffffffffffff0(%rbp)//将rax赋值给r_val所在的内存
long *p_val = &val;
lea 0xffffffffffffffe8(%rbp),%rax//将val所在的内存地址赋值给rax
mov %rax,0xffffffffffffffe0(%rbp)//将rax赋值给p_val所在的内存
我们可以看出实际上指针和引用的在g++编译器中的实现是一样的,既然分配了内存,为何&r_val == &val ? 我们来继续看看反汇编代码: tmp = &r_val;
mov 0xfffffffffffffff0(%rbp),%rax//将r_val变量中存的内存地址赋值给rax
mov %rax,0xfffffffffffffff8(%rbp)//将rax的值赋值给了tmp
tmp = &p_val;
lea 0xffffffffffffffe0(%rbp),%rax//将p_val的内存地址赋值给了rax
mov %rax,0xfffffffffffffff8(%rbp)//将rax的值赋值给了tmp
对于取地址运算(&),g++编译器对于引用和其他变量的处理是不一样的,引用调用的汇编指令mov,得到引用所在内存存储的变量内存地址,而其他变量的取地址(&)运算调用的是汇编指令lea,得到变量本身的存储地址,于是有了引用不分配内存的假象。 上述分析针对于linux下的g++编译器,传说在VC中进行编译会得到不同的结果,在debug编译下,引用是会分配内存的,而在release编译下,引用不分配内存,直接调用变量,有兴趣的童鞋可以去试试。

c++引用和指针的实现的更多相关文章

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

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

  2. nim的引用和指针

    nim语言的引用和其他语言的指针有点相似 可以提供一种“多对一”的关系 这就意味着不同的引用可以指向同一个内存位置 nim区分可被追踪的引用和不可被追踪的引用 不可被追踪的引用又称为指针 可被追踪的引 ...

  3. C++中引用与指针的区别(详细介绍)

    C++中引用与指针的区别(详细介绍) C++中的引用与指针的区别   指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一 ...

  4. C++ 中引用与指针的区别

    1.引用只是变量的一个别名,并不占用内存空间,而指针是一个变量,里面保存着被指向的变量在内存中的地址: 2 引用只能在定义时被初始化一次,之后不可变,而指针可变: 3 引用没有 const,指针有 c ...

  5. [ZZ]C++中,引用和指针的区别

    (1) 引用总是指向一个对象,没有所谓的 null reference .所有当有可能指向一个对象也由可能不指向对象则必须使用 指针. 由于C++ 要求 reference 总是指向一个对象所以 re ...

  6. Java中到底有没有指针;同时注意引用和指针的区别

    Java中引用的作用类似于指针,但是有区别:()    (1) 指针必然指向一个内存地址,如果你定义的时候不指定,就会乱指(很可能造成安全隐患)但是引用定义出来后默认指向为空.     (2) 指针可 ...

  7. java定义类 对象,引用,指针

    java是根据面向对象编程,因此有类和对象的概念,类分为普通类与抽象类. 一.定义类 类由N个 构造器  成员变量  方法组成,可以不定义,也可以根据语法定义N个. [修饰符] class 类名{ 构 ...

  8. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

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

    1:引用的和指针在概念上的区别 引用是变量的别名,例如 int m; int &n=m; 引用作为一个别名.它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用 ...

  10. 浅谈C/C++引用和指针的联系和区别

    为什么C/C++语言使用指针? 答案:①一方面,每一种编程语言都使用指针.不止C/C++使用指针. 每一种编程语言都使用指针.C++将指针暴露给了用户(程序员),而Java和C#等语言则将指针隐藏起来 ...

随机推荐

  1. Groovy系列-groovy比起Java--有哪些地方写起来更舒服?

    groovy比起java-有哪些地方写起来更舒服 java发展缓慢,语法落后冗余 说起java,其实java挺好的,java现在的性能也不错,但是,java的语法显然比较落后,而且冗余,getter/ ...

  2. LeetCode:螺旋矩阵||【59】

    LeetCode:螺旋矩阵||[59] 题目描述 给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵. 示例: 输入: 3 输出: [ [ 1, 2, 3 ...

  3. Linux基本命令 帮助命令

    命令名称:man 英文原意:manual 命令所在路径:/usr/bin/man 执行权限:所有用户 语法:man [命令或者配置文件] 功能描述:获取帮助信息 例如:man ls 查看ls命令的帮助 ...

  4. canvas 视频音乐播放器

    canvas 视频音乐播放器 var play_nor_img_path = 'images/play_btn_n.png'; //播放按钮 正常时 60x60 px var play_sec_img ...

  5. CentOS 6.5 下的截图方法

    1.利用命令模式 捕获整个屏幕 : $ gnome-screenshot 截完屏之后我们可以设置自定义图片存储位置,如图: 捕获当前终端Terminal : $ gnome-screenshot -w ...

  6. win7 加载 usb3.0驱动

    1.去微软官网下一个 usb3.0 驱动 https://downloadcenter.intel.com/zh-cn/download/26254/-NUC-NUC6i7kyk-USB3-0-Win ...

  7. 项目打包部署到tomcat操作步骤

    对于项目部署到tomcat中,需进行一下步骤: 1.对于项目打war包,方式有以下几种:install一下   找到war包的路径即可 另外:在eclipse中,选中项目 1.1 选中Export 1 ...

  8. 字符串问题之 去掉字符串中连续出现K个0的子串

    字符串中刚好出现K个连续的‘O’,则把K个连续‘O’字符去除,返回处理后的字符串 比如 str="AOOOOOBOOO"   k=3, 返回“AOOOOOB” 这个题的解决思路也有 ...

  9. 【bzoj1318】[Spoj744] Longest Permutation(乱搞)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1318 这道题的大意是要求一个长度为len,并包含1~len所有数,并使len最大的子区 ...

  10. 基于docker环境,搭建 jetty环境, 部署java项目

    前提: 1.Ubuntu 系统. 2.docker环境已经安装好. 实现步骤: 1.上docker hub 下载jetty docker 镜像. 执行命令:$ sudo docker pull jet ...