首先什么是引用?我将使用程序来回答你:
通过上面的代码可以看出来,所谓的引用实际是存放有被引用对象的地址的"只读"数据,它与指针的差别是前者是只读的,后者是可读写的.
再来引用的使用
来看看生成的汇编代码(省略部分代码)
首先来个最简单的代码:
int i = 10;
int &ri = i;
int *p = &i;
看看生成的代码:
//对i变量的说明
.globl i
.data
.align 4
.type i, @object
.size i, 4
//分配int i的内存并初始化
i:
.long 10
//对ri的说明,注意引用是放在rodata中的
.globl ri
.section .rodata
.align 4
.type ri, @object
.size ri, 4
//看看ri里面存放的内容,i的地址
ri:
.long i
//指针p的类型说明,注意他不是只读的
.globl p
.data
.align 4
.type p, @object
.size p, 4
//指针p存放的内容也是i的地址
p:
.long i
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
.section .note.GNU-stack,"",@progbits
通过上面的代码可以看出来,所谓的引用实际是存放有被引用对象的地址的"只读"数据,它与指针的差别是前者是只读的,后者是可读写的.
再来引用的使用
#include <iostream>
int i = 10;
int &ri = i;
int *p = &i;
void func(int &a)
{
a = 10;
std::cout << &a << std::endl;
}
int main(int argc, char **argv)
{
func(ri);
func(i);
return 0;
}
来看看生成的汇编代码(省略部分代码)
.globl i
.data
.align 4
.type i, @object
.size i, 4
i:
.long 10
.globl ri
.section .rodata
.align 4
.type ri, @object
.size ri, 4
ri:
.long i
.globl p
.data
.align 4
.type p, @object
.size p, 4
p:
.long i
.text
_Z4funcRi:/*func的定义,名字被wrap了,这是C++实现重载的方法*/
subl $24, %esp
movl 8(%ebp), %eax/*取得引用a,参考main函数的代码可知道现在%eax中存放的是被引用对象的地址*/
movl $10, (%eax)/*给引用赋值,实际就是给被引用对象赋值*/
movl 8(%ebp), %eax /*获得引用的地址操作,实际是获得被引用对象的地址*/
movl %eax, 4(%esp)
main:
andl $-16, %esp
subl $16, %esp
movl ri, %eax /*将引用的数值即被引用对象的地址压栈*/
movl %eax, (%esp)
call _Z4funcRi
movl $i, (%esp)/*将i地址压栈*/
call _Z4funcRi
从上面的分析可以看出来,所谓的引用实际只是对被引用对象的地址的操作