引用的簡單概念: 引用不是新定義乙個變數,而是給已存在變數取了乙個別名,編譯器不會為引用變數開闢記憶體空間,它和它引用的變數共用同一塊記憶體空間。
引用一般被使用做引數/返回值這樣可以提高效率, 減少拷貝。
在語言層面引用是乙個物件的別名不佔據空間, 但是實際上在底層的實現上引用是類似於指標實現的。
我們借助**進行探索
int i=5;
int&ri=i;
ri=8
;
通過:除錯->視窗->反彙編
int i=5;
00a013de mov dword ptr [i],5
//將文字常量5送入變數i
int&ri=i;
00a013e5 lea eax,
[i]//將變數i的位址送入暫存器eax
00a013e8 mov dword ptr [ri]
,eax //將暫存器的內容(也就是變數i的位址)送入變數ri
ri=8
;00a013eb mov eax,dword ptr [ri]
//將變數ri的值送入暫存器eax
00a013ee mov dword ptr [eax],8
//將數值8送入以eax的內容為位址的單元中
return0;
00a013f4 xor eax,eax
在彙編**中,ri的資料型別為dword,也就是說,ri要在記憶體中佔據4個位元組的位置。所以,ri的確是乙個變數,它存放的是被引用物件的位址。
我們可以將引用以指標的方式進行替換, 替換之後反彙編會發現和引用的彙編**一摸一樣。
因此得出結論在底層,引用變數由指標按照指標常量的方式實現。
引用在定義時必須初始化,指標沒有要求
引用在初始化時引用乙個實體後,就不能再引用其他實體,而指標可以在任何時候指向任何乙個同型別實體
沒有null引用,但有null指標
引用自加即引用的實體增加1,指標自加即指標向後偏移乙個型別的大小
有多級指標,但是沒有多級引用
訪問實體方式不同,指標需要顯式解引用,引用編譯器自己處理
引用比指標使用起來相對更安全
禁止給陣列進行引用,以免帶來資料二義性(改變陣列成員還是改變引用物件)
關於引用初始化後不能更改指向的物件:
c++ 之中的引用的本質上是指標,底層是乙個指向被引用物件的指標。而每乙個使用引用的地方該指標被自動解引用了,用你例子為例:b是乙個引用變數,底層儲存的是a的指標,當我們使用b的時候自動解引用,可以理解為使用b的地方被替代為 *(&a)所以引用變數一旦經過初始胡我們就無法訪問到b實際的記憶體。無法改變b的指向,b一生一世只能是a的引用。
#include
using
namespace std;
intmain
(int argc,
char
* ar**)
&i:
0038fc1c
&j:0038fc10
&pi:
0038fbf8
&pj:
0038fbec
&addr:
0038fbe0
&dis:
0038fbd4
distance:-12
addr:
0038fc04
5100
仔細觀察**和輸出結果可以得出如下結論:
(1)win32(windows 32bits)平台下,int型變數和指標變數都占用4個位元組,但是&i-&j=-12,並非想象中的4。
原因有二:
一是區域性變數儲存在棧空間,棧在主存中的生長方向是從高位址到低位址,因此i和j的位址差為負數;
二是debug模式下,int變數前後均新增4個位元組的除錯資訊,故乙個int占用了12位元組。模式設為release,就會發現棧上連續定義的int變數,位址相差4個位元組。
(2)指標變數pi與int變數j位址間相差了24位元組,按照推理,如果引用r不占用記憶體空間,那麼位址差應該為12位元組,這也說明了引用變數在記憶體占用空間。
(3)將引用變數r理解成指標,間接的獲取r的位址並修改r的值,使r指向變數j。從引用的角度理解就是將引用r與j繫結。對r賦值,結果顯示j的值被修改。
利用以上程式可以看出「引用「本身的確是乙個變數,它存放被引用物件的位址。並且,利用特殊手段能夠找到這個引用變數的位址並修改其自身在記憶體中的值,從而實現與其他物件的繫結。
這個程式在vs環境下的release模式,編譯不通過,會出現記憶體訪問衝突,無法通過引用變數r修改j的值,可能與 release模式下編譯器對引用的優化有關。與此同時,該程式可移植性很差,在64bits平台上,由指標轉換為int可能會發生截斷從而丟失資料。其次,如果引用變數前的變數不是int型,考慮到記憶體對齊等因素,要準確計算引用變數的位址不是一件容易的事,很可能跟具體的編譯器和執行環境相關。因此,研究此程式的目的是為了對引用變數的底層實現機制有所了解。在實際使用中,還是要遵循c++語言對引用制定的規範。
c++引用的本質
vs棧上連續定義的int變數,位址為什麼相差12個位元組
Ajax學習 理解 Ajax 及其工作原理
ajax是 asynchronous j ascript and xml 以及 dhtml 等 的縮寫.下面是 ajax 應用程式所用到的基本技術 html 用於建立 web 表單並確定應用程式其他部分使用的字段。j ascript 是執行 ajax 應用程式的核心 幫助改進與伺服器應用程式的通訊。...
深入理解Git原理 祖先引用
祖先引用是一種指明乙個提交的方式。如果你在引用的尾部加上乙個 git 會將其解析為該引用的上乙個提交。假設你的提交歷史是 git log pretty format h s graph 734713b fixed refs handling,added gc auto,updated tests d...
的引用 CSS及其引用
前言 1 知識點 一 css的基本語法 1.基本語法 selector 2.語法說明 1 選擇器 選擇器可以是html標記或屬性的值或自定義的識別符號。2 屬性 屬性值對 屬性 屬性值 必須一一對應,屬性與屬性值之間必須用 連線,每個屬性 屬性值用 分隔。3 屬性 css中屬性名為兩個或兩個以上的單...