首先什么是引用?我将使用程序来回答你:
首先来个最简单的代码:
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
从上面的分析可以看出来,所谓的引用实际只是对被引用对象的地址的操作