2013-07-06 36 views
3

我寫了一個小程序:這個函數的機制是什麼?

#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; 
} 

的輸出(如預期):

1 
0x7fff5ed36894 
1 
0x7fff5ed36894 

它的工作原理,因爲我希望它是,但我很好奇這是怎麼內部實現。它是函數重載還是其他函數,或者其中一個函數是圍繞另一個函數提供的包裝,以提供用戶友好性,或者編譯器自己進行投射?

+0

'z'是's'的別名。無論您在初始化後使用'z'還是使用'z',都可以在它所綁定的對象上執行。所以'raw(s)'和'raw(z)'必須給出相同的輸出,因爲它們在相同的輸入上工作(假設參考透明度在這裏) –

+0

@AndyProwl我知道引用是一個別名。我想知道他們是如何在內部實施的。我已經提到過,「他們按預期工作」。 –

回答

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) 

LEA(在lea eax,[s])指加載有效地址,所以你可以看到如何有效z包含一個指向的s位置。

在函數調用之前準備參數的指令清楚地表明您在兩種情況下都獲得(相同)指針作爲輸入。

這是非優化的代碼。

3

內部此

int s= 1; 
int &z=s; 
raw(s); 
raw(z); 

進行了優化,這一點:

int s = 1; 
raw(s); 
raw(s); 

因爲你做int &z = s;變量z後,將化名爲S以結束其生命週期結束。所以基本上它會和s一樣。

+0

如果我們有一個'const'引用會發生什麼。這是不能做到的。是真的嗎? –

+0

我的意思是:'const int &z=s;' –

+0

在這種情況下,它會被優化,但只有在沒有編譯錯誤的情況下才會被優化,但在你的例子中會有。而這個賦值'const int &z=s;'自動從非const轉換爲const –

5

當編譯器爲你的程序產生的代碼,它看到&說,這是一個參考的時候,它確實產生指針變量[什麼的,機器代碼,類似於一個指針。

因此z本身將保留地址s

當您調用raw(s)時,編譯器會說「啊,所以原始參數是一個引用,這意味着地址s」。當您執行raw(z)時,編譯器會說「啊,我們已經有一個參考,所以我們只傳遞z」的內容,因爲您之前將它設置爲s,與s的地址相同。

這完全是因爲它應該是。

相關問題