这个功能背后的机制是什么?

Ama*_*tam 3 c++ function

我写了一个小程序:

#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)

它的工作方式与我预期的一样,但我很好奇这是如何在内部实现的.它是函数重载还是别的东西,或者其中一个函数是另一个函数的包装器,以提供用户友好性或编译器自己进行转换?

Ton*_*ony 7

这是它在汇编程序中的外观:

    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指令清楚地表明在两种情况下都得到(相同)指针作为输入.

这是非优化代码.


Mat*_*son 5

当编译器为你的程序生成代码时,当它看到&这是一个引用的说法时,它确实产生了一个指针变量[或者在机器代码中类似指针的东西].

因此z,将保留地址s.

当你打电话时raw(s),编译器说"啊,所以raw的参数是一个参考,意思是地址s".当你这样做时raw(z),编译器会说"啊,我们已经有了一个引用,所以我们只需要传递"的内容z,因为你将它设置为s更早,就是与之相同的地址s.

这完全是应该的.