當我學習c++引用時,聽到的第一句話是「引用是變數的別名,不像指標一樣需要占用記憶體空間」。然而學到深處,發現此話並不完全正確。
本文主要介紹我如何通過實驗來了解到c++引用的實現,其實引用的內部就是指標。當然這也於編譯器有關,所以這裡需要提及一下測試所用的編譯器及環境。
測試環境是mingw的g++ 8.1.0,64位編譯器,64位的機子。所以指標的大小是8個位元組,即64個bit。(注:因為目的是測試,所以測試時並沒有處理對new操作符所產生物件的**)
首先我寫出了如下**,試圖通過指標偏移來獲取有關引用的資訊:
#include #include using namespace std;
int main()
然而,這個程式的輸出如下(str的輸出忽略):
0x61fe00
0x61fdf8
難道引用真的不佔記憶體?編譯器真的很聰明,可能優化掉了吧;經過一系列嘗試,我寫出了另外一段**:
#include #include using namespace std;
void foo(int64_t q, string& s, int64_t r)
int main()
這段**的輸出是:
main(): 0x1e1bd0
&q: 0x61fde0
&r: 0x61fdf0
*(string**)(&q + 1): 0x1e1bd0
可見,q的位址是0x61fde0
,r的位址是0x61fdf0
。兩個位址間相差16個位元組!這裡引用占用的記憶體出來了。顯然引用對應的指標儲存在q的8個位元組之後。我們可以將q的位址加1,也就是加上8個位元組,這裡儲存的就是引用的資訊。假設它就是指標,那麼考慮:(&q + 1)
本身是乙個指向string*
的指標,也就是string**
。所以若要獲取指標的值,需要對這個值解一次引用,輸出出來。(當然如果你想簡單一點,可以直接把它轉成int64_t
然後用16進製制輸出亦可)
至此真相大白,程式輸出的最後一行0x1e1bd0
與主函式中new出來的物件的位址(見輸出第一行)一致。所以得出結論:引用是用指標實現的。使用者對引用的訪問操作都內含一次解引用,而這對使用者來說是透明的。
不過需要提及的是,回想本文的第乙個測試,發現引用的指標空間被優化掉了。所以引用有時也不一定會在棧上真正以指標體現出來。
c 引用極其底層實現
一 c 中引用的語法是這樣的 int x 100 int x x 它的意思就是是給變數x起了乙個別名,在以後的 中,x其實就是x,這兩個是等價的。舉個例子,在 唐伯虎點秋香 中,唐伯虎叫做華安,又叫做9527,其實這三個名字都是同乙個人,引用就是這個意思。注意事項 引用初始化的時候一定要繫結乙個變數...
理解C 中引用的底層實現
1 c primer提到 引用並非物件,相反的,它只是為乙個已經存在的物件所起的另外乙個名字。引用的定義必須伴隨初始化,而且一旦定義了引用,就無法令其再繫結到另外的物件,之後每次使用這個引用都是訪問它最初繫結的那個物件。2 何為物件?對於物件導向來說,物件就是類的例項,是抽象化的資料本身。更廣義的來...
深入探索C 引用的實現原理
1.引用的概念及用法 引用不是定義乙個新的變數,而是給乙個已經定義的變數重新起乙個別名。定義的格式為 型別 引用變數名 已定義過的變數名 int a 1 int b a 引用的特點 1.乙個變數可取多個別名 2.引用必須初始化 3.引用只能在初始化的時候引用一次,不能改變為再引用其他的變數。可見,a...