引用到底在我們的背後做了什麼

2021-06-29 15:34:07 字數 2654 閱讀 8703

引用到底在我們的背後做了什麼?

最近專案**中有用到後值引用,一直想鑽研一翻,但是有兩個基礎的問題始終沒有找到答案,今天在借助度娘的實力後,再稍加研究,終於明白,在此記錄下來,以在以後需要檢視的時候留下痕跡,也給正在學習的朋友相互交流的機會;

1.首先我們看一下非常量左值引用,**如下:

int_tmain

(int

argc

,_tchar

*argv

) 編譯,有兩個錯誤,很多同學一看就知道是什麼問題,但是我們還是分析一下,加深一下印象:

1)第乙個錯誤,就是用int &rleft_a2 = 100; 編譯器的錯誤提示,不是很友善,無法從int轉換為int &, 但是我們左值引用不就是把type&來繫結type型別嗎?是的,但是我們看一下引用的定義,左值引用需要繫結的是乙個物件(左值) ,

a>什麼是左值呢?左值 就是恆久存在的

b>100在這,它是乙個字面常量,他是沒有記憶體空間的,只能放在"="右邊的,所以它應該稱做是右值; 為什麼我們的左值引用不能繫結到右值上呢?右值通常是臨時的物件(如果把每個資料型別看作乙個資料模型的話,那通過資料模型創造出來的每個變數我們就姑且稱它為資料模型的物件,個人覺得如此容易理解記憶),它可能在出現所在的語句結束後就會釋放(析構), 用左值引用,再次訪問,可能訪問到已經釋放(析構)的記憶體對應的空間,那將可能會導致乙個未知的錯誤,這也是編譯器絕對不允許的;

2)第二個錯誤, int &rleft_a3 = n;  編譯器給的提示相對友好,無法從

「const int」轉換

為「int &」,   從上面的語句 const int n = 200;我們可以看出n 是乙個具有const屬性的常變數,也有人直接稱之為常量,const的作用是讓它值不可改變, 如果我們定義乙個非常量左值引用繫結到乙個常變數上,那我們在改變引用的同時,是不是就等於改變到常變數的屬性上了呢!那const屬性就沒有起到相應的作用, 因此乙個非const引用也是絕對不可以繫結到乙個常變數的引用上的;

2. 常量左值引用  const &:

int_tmain

(int

argc

,_tchar

*argv

) 上面的**編譯,完全通過沒有問題,const常量左值引用可以直接繫結到常量左值, 非常量左值,和常量右值上;

對於前面的兩行**, 

const常量左值引用可以直接繫結到常量左值, 非常量左值,很容易推演出來,第三行,有人就要問了,為什麼乙個const左值引用就可以繫結到乙個字面值常量上呢,乙個字面值常量都沒有放在記憶體中,沒有空間,繫結又是怎麼實現的呢?下面我們通過visual stdio 的反彙編功能檢視一下彙編**,如下:

inti

=100;

001113

d8movdword

ptr[i]

,64 h

const

intn

=200;

001113

dfmovdword

ptr[n]

,0 c8h

const

int&

const_rleft_a=i

; 001113e6

leaeax,[

i]001113e9

movdword

ptr[

const_rleft_a],

eax

const

int&

const_rleft_a2=n

; 001113

ecleaeax,[

n]001113

efmovdword

ptr[

const_rleft_a2],

eax

const

int&

const_rleft_a3

=100;

001113

f2movdword

ptr[

ebp-

48h]

,64 h

001113

f9leaeax,[

ebp-

48h]

001113

fcmovdword

ptr[

const_rleft_a3],

eaxconst常量左值引用繫結到常量左值, 非常量左值

,都是直接把變數的位址存至暫存器eax中, 再將eax暫存器中的位址對應的內容,賦值給const引用變數; 我們再看看const int &const_rleft_a3= 100;這一句反彙編後,**的和前面略有不同, 他是先將100(也就是64h,十六進製制64就是100)存在ebp-48h這樣乙個臨時的位址中,我對彙編不太懂,暫且把它理解為,編譯器偷偷開闢了乙個臨時空間,位址為ebp-48的偏移

值,用於存放100這個字面常量,此時的字面值常量已經完全的轉化成了乙個臨時物件,再將位址傳至暫存器eax中,再將eax暫存器位址對應的空間資料存放在const_rleft_a3的位址對應的空間中;其實它之所以可以繫結到乙個字面值常量上,是因為編譯器在背後所做的手腳,將字面值常量偷偷轉成了乙個臨時物件,這個臨時物件的生命週期應該也會根據cont & 的繫結,生命週期將延長至引用物件的生命週期一致,在c++11之前沒有右值引用,通過const左值引用來實現對乙個字面值常量來實現繫結;

左值:持續存在,強調的是記憶體所在的空間;  右值:臨時物件,即將被銷毀,生命周期短,強調的是物件的值; 

作為AI產品經理,我們到底在優化什麼?

大資料文摘出品 編譯 張強 睡不著的iris 周素雲 使用者體驗與人工智慧 ai 之間有什麼樣的關係?這種關係對產品經理而言又意味著什麼?這兩個問題非常重要,因為它會影響產品的使用者體驗及其價值主張。本文作者guy molho,是一位經驗豐富的產品經理。曾經用了15個月的時間,在沒有涉足太多細節的情...

傳引用,到底傳遞的什麼?

今天在c 課上,老師模稜兩可地說了說 c 的引用,竟然犯了引用能指向另乙個變數的錯誤。廢話不多說,傳引用,究竟是傳什麼?第乙個感覺是傳位址,下邊讓我們驗證一下。這個是我寫的一段測試 實現了兩個變數的值交換。轉到vc 的反彙編下觀察 主函式中對swap 函式的呼叫部分 swap m,n 0102153...

雜談 我們的現代化管理到底在管什麼?

這篇文章也源於現實生活的乙個實際事件,整個事情是這樣的 一天,筆者正在參與公司內部的乙個與會人數超百人的會議,到場人數比較多,會議內容也比較重要,所以現場有2套投影裝置,方便與會者 ppt,過去了約15min,正當大家會議逐漸深入的同時,意外發生了,其中一套投影裝置發生了故障,不能夠正常投影,不過主...