c++引用本质
首先先来看一段代码:
int main() {
char var = 'A';
char& refVar = var;
char* ptrVar = &var;
cout << refVar;
cout << ptrVar;
}
通过vs调试模式下查看反汇编有如下结果:
char& refVar = var;
000D2A3C lea eax,[var]
000D2A3F mov dword ptr [refVar],eax
char* ptrVar = &var;
000D2A42 lea eax,[var]
000D2A45 mov dword ptr [ptrVar],eax
很显然变量refVar和ptrVar所指向的内存地址都保存了变量var的地址,即代码中的[var]。
cout << refVar;
000D2A48 mov eax,dword ptr [refVar]
000D2A4B movzx ecx,byte ptr [eax]
000D2A4E push ecx
...
000D2A56 call std::operator<<<std::char_traits<char> > (0D1532h)
...
cout << ptrVar;
000D2A5E mov eax,dword ptr [ptrVar]
000D2A61 push eax
...
000D2A69 call std::operator<<<std::char_traits<char> > (0D153Ch)
...
有趣的来了,在调用cout函数输出refVar和ptrVar的时候,前者将refVar得值所指向的内存地址的值作为参数(即var),而后者则直接将ptrVar得值作为参数(即&var)。
是不是很神奇,其实C/C++的汇编代码都一致,不同在于C++的一些特性如const、private都是通过编译器来实现,引用的本质上是一个常量指针。只不过在编译器层进行相应的处理,使得程序员在使用时直觉上认为引用就是变量的别名。如上所示输出refVar的时候编译器的处理是先获得refVar的值,再以该值作为地址去访问数据,而在输出指针所指向的值时需要程序员自己来实现这些操作,否则只能输出地址值。