以下汇编都是x86汇编
写一段简单的语句,看其汇编
int i = 1;
int & ii = i;
0x080483f3 movl $0x1,-0x10(%ebp)
0x080483fa lea -0x10(%ebp),%eax
0x080483fd mov %eax,-0x8(%ebp)
第一句是将1赋值给i,第二句将i的地址放入eax中,第三句将eax中的值传给ii。可见引用就是从一个变量处取得变量的地址,然后赋值给引用变量。
再看一句右值引用的汇编
int && iii = 10;
0x08048400 mov $0xa,%eax
0x08048405 mov %eax,-0xc(%ebp)
0x08048408 lea -0xc(%ebp),%eax
0x0804840b mov %eax,-0x4(%ebp)
第一句将10赋值给eax,第二句将eax放入-0xc(%ebp)处,前面说到“临时变量会引用关联到右值时,右值被存储到特定位置”,在这段程序中,-0xc(%ebp)便是该临时变量的地址,后两句通过eax将该地址存到iii处。
通过上述代码,我们还可以发现,在上述的程序中-0x4(%ebp)存放着右值引用iii,-0x8(%ebp)存放着左值引用,-0xc(%ebp)存放着10,而-0x10(%ebp)存放着1,左值引用和右值引用同int一样是四个字节(因为都是地址)
同时,我们可以深入理解下临时变量,在本程序中,有名字的1(名字为i)和没有名字的10(临时变量)的值实际是按同一方式处理的,也就是说,临时变量根本上来说就是一个没有名字的变量而已。它的生命周期和函数栈帧是一致的。也可以说临时变量和它的引用具有相同的生命周期。
总结:
1、左值和右值引用本质没有什么区别,都是取地址!(左值引用有自己的内存空间)
2、左值是取现有变量地址,右值则需要创建临时存储并取地址.(右值引用有自己的内存空间)