引用的实现
科学让个人按照个人的嗜好取喜爱合乎他气质的东西,特别用心研究于他精神最投机的东西。--- 丹纳(法国史学家和批评家,1828-1893)
最近一个朋友问起我一个关于引用的问题。
我开始很想回答他引用不可重新指向,引用就是变量的别名,引用的安全性比较好,等等。
后来一想,引用到底是什么?有自己的内存吗?
首先还是看看编译器中引用的实现吧:
//
RefTest.cpp
void test()
{
int a = 1 ;
// 00401038 mov dword ptr [ebp-4],1
int & ra = a;
// 0040103F lea eax,[ebp-4] ;变量a的地址存入eax
// 00401042 mov dword ptr [ebp-8],eax ;将eax中的内容即变量a的地址放入[ebp-8]对应的内存单元中
int b = ra + 5 ;
// 00401045 mov ecx,dword ptr [ebp-8] ;变量a的地址存入eax
// 00401048 mov edx,dword ptr [ecx] ;a的值放入到edx
// 0040104A add edx,5 ;加5
// 0040104D mov dword ptr [ebp-0Ch],edx ;得到b的值
}
int main()
{
test();
return 0 ;
}
void test()
{
int a = 1 ;
// 00401038 mov dword ptr [ebp-4],1
int & ra = a;
// 0040103F lea eax,[ebp-4] ;变量a的地址存入eax
// 00401042 mov dword ptr [ebp-8],eax ;将eax中的内容即变量a的地址放入[ebp-8]对应的内存单元中
int b = ra + 5 ;
// 00401045 mov ecx,dword ptr [ebp-8] ;变量a的地址存入eax
// 00401048 mov edx,dword ptr [ecx] ;a的值放入到edx
// 0040104A add edx,5 ;加5
// 0040104D mov dword ptr [ebp-0Ch],edx ;得到b的值
}
int main()
{
test();
return 0 ;
}
以上是在VC6下得到的结果。
下面是GCC3.4下对应的test()的部分代码:
movl $
1
,
-
4
(
%
ebp)
leal - 4 ( % ebp), % eax ; 将变量a的地址放入eax中
movl % eax, - 8 ( % ebp) ; 将eax中的值(即变量a的地址)放入 - 8 ( % ebp)对应的内存单元中
movl - 8 ( % ebp), % eax ; 将 - 8 ( % ebp)对应的内存单元中的值(还是变量a的地址)放入eax中
movl ( % eax), % eax ; 寄存器间接寻址,结果事将变量a的值放到eax中
addl $ 5 , % eax ; eax中的值加5
movl % eax, - 12 ( % ebp) ; 得到b
leal - 4 ( % ebp), % eax ; 将变量a的地址放入eax中
movl % eax, - 8 ( % ebp) ; 将eax中的值(即变量a的地址)放入 - 8 ( % ebp)对应的内存单元中
movl - 8 ( % ebp), % eax ; 将 - 8 ( % ebp)对应的内存单元中的值(还是变量a的地址)放入eax中
movl ( % eax), % eax ; 寄存器间接寻址,结果事将变量a的值放到eax中
addl $ 5 , % eax ; eax中的值加5
movl % eax, - 12 ( % ebp) ; 得到b
可见,两个编译器在堆栈中都增加了一个变量,存放a的地址。我们的确可以只把ra看作a的一个别名,但是从VC和GCC实现的角度讲,还是把引用看作是一个指针变量来实现的。
回过头看开头的两个问题。第一个是引用到底是什么,C++标准中也只是指出引用是一种declarators,然后也只是给出了引用的形式和作用。第二个问题是有没有对应的内存,C++标准中说:It is unspecified whether or not a reference requires storage.(ISO/IEC 14882 Programming Languages-C++, 8.3.2, p132),即依赖于编译器的实现,从上面的例子看,引用是有存储的,其内容是引用对应的变量的地址,而在使用引用的时候,又会先取地址值,然后根据这个地址值来取引用对应的变量值。
(另:csdn中加代码怎么是不等宽字体呀,所以才出现了代码的不对齐,有点郁闷。)