我写了一个小程序:
#include <iostream>
using namespace std;
int raw(int &x) {
cout<<x<<endl;
cout<<&x<<endl;
}
int main () {
int s= 1;
int &z=s;
raw(s);
raw(z);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是(如预期的那样):
1
0x7fff5ed36894
1
0x7fff5ed36894
Run Code Online (Sandbox Code Playgroud)
它的工作方式与我预期的一样,但我很好奇这是如何在内部实现的.它是函数重载还是别的东西,或者其中一个函数是另一个函数的包装器,以提供用户友好性或编译器自己进行转换?
这是它在汇编程序中的外观:
int s= 1;
002044A8 mov dword ptr [s],1
int &z=s;
002044AF lea eax,[s]
002044B2 mov dword ptr [z],eax
raw(s);
002044B5 lea eax,[s]
002044B8 push eax
002044B9 call raw (020110Eh)
002044BE add esp,4
raw(z);
002044C1 mov eax,dword ptr [z]
002044C4 push eax
002044C5 call raw (020110Eh)
Run Code Online (Sandbox Code Playgroud)
LEA(in lea eax,[s])表示加载有效地址,因此您可以看到如何z有效地包含指向位置的指针s.
在函数调用之前准备参数的push指令清楚地表明在两种情况下都得到(相同)指针作为输入.
这是非优化代码.
当编译器为你的程序生成代码时,当它看到&这是一个引用的说法时,它确实产生了一个指针变量[或者在机器代码中类似指针的东西].
因此z,将保留地址s.
当你打电话时raw(s),编译器说"啊,所以raw的参数是一个参考,意思是地址s".当你这样做时raw(z),编译器会说"啊,我们已经有了一个引用,所以我们只需要传递"的内容z,因为你将它设置为s更早,就是与之相同的地址s.
这完全是应该的.
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |