1. 引用变量其实和指针变量在内部实现上是一样的(包括定义、作为右值等操作)。
2. 引用变量与指针变量本身在符号表中的保存机制不一样的(符号表中保存变量的名字以及其地址)。指针变量保存的地址是指针变量自身的地址、而引用变量保存的是其引用对象的地址值。(这个结论也可以用来说明引用的一些特性:声明时就要初始化,因为其符号表中保存的地址要用其对象的地址,对象不初始化就没有分配内存,没有地址;引用的对象初始化后不能被改变了,因为符号表本身创建了之后是不能再被修改的。)
下面看一下编译器是如何处理指针和引用的:
int i = 10;004113EE mov dword ptr [i],0Ah int* p = &i;004113F5 lea eax,[i]004113F8 mov dword ptr [p],eax int &r = i;004113FB lea eax,[i]004113FE mov dword ptr [r],eax //指针和引用的保存的都是对象的地址,本质上是一样的 int k = i;00411401 mov eax,dword ptr [i]00411404 mov dword ptr [k],eax int m = *p;00411407 mov eax,dword ptr [p]0041140A mov ecx,dword ptr [eax]0041140C mov dword ptr [m],ecx int n = r;0041140F mov eax,dword ptr [r]00411412 mov ecx,dword ptr [eax] //变量r的值其实是地址,只是编译器在其作为右值时,做了一步转化00411414 mov dword ptr [n],ecx cout<<(&r)<>::operator<< (4182A4h)]004138BB cmp edi,esp004138BD call @ILT+335(__RTC_CheckEsp) (411154h)004138C2 mov ecx,eax004138C4 call dword ptr [__imp_std::basic_ostream >::operator<< (4182A8h)]004138CA cmp esi,esp004138CC call @ILT+335(__RTC_CheckEsp) (411154h)