觀看了唐老師講解的一節《第5課 - 引用的本質分析》感覺非常不錯,有深度不廢話,我喜歡~~~
再此總結下,并且奉上視訊下載下傳位址~~~
//----------------------------------------------正文----------------------------------------------
在C裡并沒引用這個文法,而在C++裡具有這個文法。為什麼C++要添加引用這個文法?
我的了解就是引用就是對指針的封裝!
首先,指針變量有多種種形态:p *p &p;
1)p: 代表指針變量中存放的位址值,這個位址值一般就是某個變量的記憶體位址。
2)*p: 對應的是,p裡存放的記憶體位址中的值。
3)&p: 存放指針變量的記憶體位址。
使用指針就意味着随時,形态的轉變,如取位址,解引用。有時候了解稍微偏差,忘記取位址或者是解引用,就會出現莫名其妙的問題。
為了簡化指針的使用,并且和指針擁有一樣的強大功能,引用就出現了。
先看一段程式:


1、b0為普通變量,int b0 = a0;僅僅是簡單的指派,是以改變b0的值無法改變
a0的值,它們關聯不同的記憶體空間。
2、b1為指針變量,int* b1 = &a1;這一句将a1的位址給b1這個指針變量。
3、b2為a2的引用,int& b2 = a2;就表示b2和a2關聯上了。從此它們同氣連枝不分彼此。引用這段程式和普通變量那段程式相比解決多了一個&而已,但是卻達到了指針的效果。省去了指針解引用取位址這樣的過程。看上去就給同一塊記憶體空間取了兩個名字,這兩個名字任意一個都可以對這篇記憶體進行操作。
知道了引用的好處,再來分析他的原理,之前說過我的了解引用就是對指針的封裝,其實在引用的背後,其實就是指針,隻是編譯器隐藏了這個細節。如何證明呢?
首先建立一個結構體:
struct TRef
{
char& r;
};
然後測試這個結構體的大小:
cout << sizeof(TRef) << endl;
發現大小為4,正好是一個指針的大小!(去掉&測試大小是1).進一步分析就得看彙編
Char& b = a; 反彙編之後變成了兩句:
第一句将a的位址放大eax寄存器,然後将eax的值及a的位址放到了b所在的位址空間,是以b裡裝的是a的位址值。這就是指針的實作過程!
是以一旦編譯器,識别到這個變量是個引用,那麼當給這個引用關聯一個變量時,編譯器自動給被關聯的變量取位址,當給引用指派常量的時候,編譯器自動給該變量解引用。
正因為,編譯器幫你自動完成了取位址和解引用,你才可以不用作這些容易出錯的事情,而且完成指針的工作。
這裡補充說明一點:
如果你直接去測試cout << sizeof(char&) << endl;的值大小是1,而不是4.這是因為,如果直接通路引用,編譯器就會幫你完成解引用這個過程,那麼你檢測的就是char而不是指針了。而放到結構體裡面 就是為了不去直接操作引用 而得到引用的特性。
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”将是我最大的寫作動力!歡迎各位轉載,但是未經作者本人同意,轉載文章之後必須在文章頁面明顯位置給出作者和原文連接配接,否則保留追究法律責任的權利。