c 中「引用」的底層實現原理詳解

2022-08-02 08:57:09 字數 1909 閱讀 9932

**:c++中「引用」的底層實現原理詳解_c/c++_lws123253的部落格-csdn部落格 

目錄:初學c++中的「引用」這一概念的時候,很多人都是懵的,大家大概都會產生這樣的疑問?

什麼是引用?

引用占用記憶體嗎?

…於是,為了驗證你的猜想,你可能會寫出下面這樣的**來驗證:

#includeusing namespace std;

int main()

執行結果:

a:address->0031fd54

b:address->0031fd54

我們會發現,引用b的位址和變數a的位址一樣。於是,有人猜想是不是說變數a和引用b本身就是乙個東西。所以同樣的,引用本身所佔記憶體就是變數a的記憶體。

**首先對於這個說法,肯定是不正確的。**至於為什麼不正確,我們接下來會以底層原理為大家解釋。

##什麼是引用

為了看看引用的底層究竟是怎樣實現的,我決定寫乙個簡短的**,然後反彙編(vs編譯環境在除錯模式下,右鍵滑鼠選單->反彙編)看一看。

#includeusing namespace std;

int main()

我們再看下轉彙編後的彙編**:  

9:       int x = 1; 	//源** 

00401048 mov dword ptr [ebp-4],1 //反彙編**

10: int &b = x; //源**

0040104f lea eax,[ebp-4] //反彙編**

00401052 mov dword ptr [ebp-8],eax//反彙編**

在這裡解釋下這三行反彙編**:

mov dword ptr [ebp-4],1 //把1賦值給ebp(棧底指標)-4的位址

lea eax,[ebp-4] //把ebp-4的位址賦值給暫存器eax

mov dword ptr [ebp-8],eax //把暫存器eax裡的值賦值給ebp-8的這塊位址

上述三行**的作用就是將1賦值給x,然後將x的位址賦值給了引用b。

而在記憶體中,它是這樣的:

建議:有興趣的同學可以了解一下常見的彙編指令,對於了解**底層原理有很大的幫助。

##引用占用記憶體嗎

通過上面的分析,我們得出了引用本身存放的是引用物件的位址,通俗點理解就是引用就是通過指標來實現的,所以,應用所佔的記憶體大小就是指標的大小。

##引用的位址

在最開始,我們寫過一段**來測試引用的位址,發現引用的位址和變數的位址是一樣的。但是,在後面對引用的底層分析後發現,它本身又存放的是變數的位址,即引用的值是位址,那麼這不是很衝突嗎?

#include#include using namespace std;

int main()

輸出:&x=12ff7c,&y=12ff78,&b=12ff74,b=12ff7c

不知道看到這裡大家明白了沒有,引用b的位址我們可以間接通過&y-1來得到b的位址,從而得到b的值:*(&y-1) 從結果可以知道,b的值即x的位址,從而可以知道,從地層實現來看,引用變數的確存放的是被引用物件的位址,只不過,對於高階程式設計師來說是透明的,編譯器 遮蔽了引用和指標的差別。

我們這裡的研究只是為了通過這段**為大家更好地解釋引用和指標的區別。

如果還不明白,我們繼續看這段**變數的記憶體布局圖:

最後要注意一點的是:引用就是引用,指標就是指標,引用不代表指標,一定不要混淆。

理解C 中引用的底層實現

1 c primer提到 引用並非物件,相反的,它只是為乙個已經存在的物件所起的另外乙個名字。引用的定義必須伴隨初始化,而且一旦定義了引用,就無法令其再繫結到另外的物件,之後每次使用這個引用都是訪問它最初繫結的那個物件。2 何為物件?對於物件導向來說,物件就是類的例項,是抽象化的資料本身。更廣義的來...

C C 中引用的底層原理

其實我們見到的大部分解釋都是這麼說的 首先我們來看看對引用取位址會發生什麼?include intmain 結果輸出如下 e99a7dec e99a7dec可以看到,對引用取位址其實就是對被引用物件取位址,所以這樣肯定行不通。但是,我們可以通過位址偏移來間接實現。include class test...

c 引用極其底層實現

一 c 中引用的語法是這樣的 int x 100 int x x 它的意思就是是給變數x起了乙個別名,在以後的 中,x其實就是x,這兩個是等價的。舉個例子,在 唐伯虎點秋香 中,唐伯虎叫做華安,又叫做9527,其實這三個名字都是同乙個人,引用就是這個意思。注意事項 引用初始化的時候一定要繫結乙個變數...