引用的本質是什麼

2021-05-25 23:50:06 字數 2233 閱讀 8676

在大學的時候,教材裡這麼說的「引用是個別名...引用作為目標的別名而使用...引用不是值不佔儲存空間...引用只有宣告,沒有定義...」

那麼,引用到底佔不佔記憶體空間,引用的本質是什麼?

下面舉個例子:

int a = 10;

int &b = a;

下面是網路上比較權威的說法;另外,還有都史用於驗證引用佔記憶體的例項。如果大家有什麼異議,本人希望與大家多多交流。

探索c++的底層機制

二.引用:你可以擁有引用,但編譯器僅擁有指標(位址)

看過了第一條,你一定對編譯器的工作有了一定的了解,實際上編譯器就是程式設計師與底層之間的乙個轉換層,它把乙個高階語言**轉換為低階語言**,乙個編譯器完成的轉換跨度越大,那麼它也就會越複雜,因為程式設計師的工作都由他代為完成了。c++編譯器必然比彙編編譯器複雜就是這個道理。如果我問你引用和指標是一樣的嗎?你或許會說當然不一樣了,指標容易產生不安全的因素,引用卻不會,真的不會嗎?我們來看下面這段**:

int *e=new int(10);

int &f=*e;

delete e;

f=30;

你認為上面這段**怎麼樣,我感覺就不很安全,它和指標有相同的隱患。因為它所引用的記憶體區域就不合法。

我個人認為,所謂的引用其實就是一種指標,只不過二者的介面並不相同,引用的介面有一定的限制。指標可以一對多,而引用卻只能一對一,即&refer不能被改變,但卻並不能說一對一就是安全的,只不過危險的係數降低罷了。引用比指標更容易控制。

ok,下面來說說指標,曾經有過彙編經驗的人一定會說,恩,指標的某些地方有些像彙編,尤其是那個「*」,怎麼就那麼像彙編中的「」啊。呵呵,的確,它也涵蓋了乙個定址的過程。看來指標的確是個比較低階的東西。然而引用卻並不那麼直接,雖然程式設計師用起來方便安全了許多。但是你要清楚,只有你可以擁有引用,編譯器可沒有這個工具,計算機並不認識這個東西。因此,它的底層機制實際上是和指標一樣的。不要相信只有一塊記憶體拷貝,不要認為引用可以為你節省乙個指標的空間,因為這一切不會發生,編譯器還是會把引用解釋為指標。不管你相不相信,請看下面這段**:

int& b=a;

lea eax,[a];

mov dword ptr[b],eax;把a的位址賦給位址為b的一塊記憶體

b=50;

mov eax,dword ptr[b];

mov dword ptr[eax],32h;

int *d=&a;

lea eax,[a];

mov dword ptr[d],eax

*d=60;

mov eax,dword ptr[d]

mov dword ptr[eax],3ch;

以上的**均來自具體的編譯器,怎麼樣,相信了吧,好,讓我再來做乙個或許不怎麼恰當的比擬,你一定編過有關線性表和棧的程式吧,線性表是乙個非常靈活的資料結構,在他上面有許多的操作,然而棧呢,它是乙個限制性操作的線性表,它的底層操作實際上是由線性表操作實現的。就好比stack與vector的關係,因此指標和引用的關係就好比線性表和棧的關係,引用也就是受限的指標,它對外的介面和指標雖然並不一樣,但底層是相同的。

下面再來看看引用的乙個重要用途,作為函式的引數傳遞的時候是怎樣的情形:

void swapr(int &a, int &b);

void swapr(int* a, int *b);

int a=10;

int b=20;

push eax; //把a的位址壓入堆疊

lea ecx,[b];

push ecx;

call swapr;

swapr(&a, &b);

lea eax,[a];

push eax;

lea ecx,[b];

push ecx;

call swapr;

怎麼樣,用引用和指標傳遞引數無論是在效率上還是在空間上都是完全一樣的,如果妄想不傳入位址就修改實參的值,簡直就是天方夜譚,這就說明引用的本質就是指標。畢竟它們的行為都太相似了,如果不是這樣,你還有什麼方法去實現引用嗎?記住,引用只不過是編譯器為你提供的乙個有用且安全的工具,對於機器**可無法表示它,它把指標一對多的缺點去除,禁止了你的不安全的操作。但回到問題的本源,他們沒有任何區別。

都史的例項:

#include

class a ;

class b

};int main() {

cout << "size of class a:"《結果:

size of class a:4

size of class b:4

變數的本質是什麼

既能讀又能寫的記憶體物件,初始化後不能修改的被叫做常量 變數就是記憶體空間的別名 程式通過變數來申請和命名記憶體空間int a 1 通過變數名訪問記憶體空間 記憶體空間可以取別名嗎?變數只是記憶體空間的別名 所以顯然當然可以取別名 通過變數操作記憶體 變數的位址是記憶體空間位址 展示 int a 1...

教育的本質是什麼?

所摘文章傳送門 我現在終於明白了教育的本質是什麼。不是教你具體的知識或技能,而是通過反覆的灌輸 上課 和練習 作業考試 讓你學會用理性戰勝感性,用屬靈的人性替代屬肉體的獸性。更通俗的說,是通過對人的反覆 抑制人類的動物本能,啟發人類的高階智慧型。什麼是動物本能?就是跟隨天然就會掌握,不用後天學習的求...

資料的本質是什麼?

2010 年,資料科學家 這個稱謂的發明者帕蒂爾 d j patil 和傑夫 哈默 jeff hammerbacher 認為,一切應該以產品為中心,從資料獲取 資料清洗 搭建和管理資料設施 原型開發 產品設計等方面,去實踐資料的價值。一 一場以大資料為核心的智慧型盛宴 時下彷彿大家都在談 人工智慧 ...