亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++引用怎么使用及底層原理是什么

發布時間:2022-04-24 14:06:51 來源:億速云 閱讀:228 作者:iii 欄目:開發技術

本篇內容介紹了“C++引用怎么使用及底層原理是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    引用

    引用不是定義一個新變量,而是給已存在的變量取了一個外號,編譯器不會為引用變量開辟內存空間,它和它引用的變量共用同一塊內存空間。

    舉個形象的例子,魯智深又被叫做"花和尚",這里的花和尚和魯智深都是同一個人,花和尚就是魯智深的引用,說白了引用其實就是取外號。

    引用的注意事項

    • 1.引用必須初始化

    int main()
    {
    int a;
    int &b =a;
    }

    這時b就是a的外號。
    下面的這種沒有初始化的做法是錯誤的

    int main()
    {
    int &b;//引用必須初始化,這里沒有進行初始化。
    }
    • 2.一個變量可以有多個引用

    在生活中,我們可能有多個名字,在家中父母可能叫你小名,在外面別人可能叫你的全名或者外號

    其實也就是一個變量可以有多個外號,也就是可以有多個引用。

    int main()
    {
    int a;
    int &b=a;
    int &c=a;
    }

    這里的b和c都是a的外號,b,c,a三個變量指向的都是同一塊內存空間。

    • 3.引用一旦引用了一個實體就不能再引用其他的實體

    形象的來說,就是你和你的親弟弟不能用同一個名字

    下圖c是a的引用,那么現在他就不能做b的引用了。

    C++引用怎么使用及底層原理是什么

    引用做參數

    在講引用做參數之前,我們先需要了解一下,參數傳值和參數傳引用的區別。

    1.參數傳值

    下圖實參傳遞了a,形參b對其進行了接收并修改,但是實參a最終并沒有受到影響,這又是為什么呢?

    C++引用怎么使用及底層原理是什么

    原來,參數傳值的時候,形參會生成一份實參數據的拷貝,也就是說實參和形參指向的不是同一塊空間,所以形參的修改不會影響實參。

    C++引用怎么使用及底層原理是什么

    2.引用傳參

    下圖進行了引用傳參,形參的修改對實參產生了影響,我們可以大膽推測形參和實參是一塊空間。

    C++引用怎么使用及底層原理是什么

    原來,引用傳參的時候,形參不再是實參的拷貝,而是實參的一個引用,也就是說實參和形參指向的是同一塊內存空間,形參的改變會影響實參。

    C++引用怎么使用及底層原理是什么

    實參傳值和傳引用的優劣

    1.實參傳值:

    缺點:形參會生成一份實參數據的拷貝,當數據量很大時,在一定程度上就會影響程序的運行速度

    優點:因為形參是實參的拷貝,所以形參的操作不會影響實參,可以防止實參數據遭到污染。

    2.實參傳引用

    缺點:形參的操作對實參會產生影響,形參的錯誤操作會讓實參數據遭到修改。

    優點:因為形參是實參的引用,一定程序上,可以提高程序的運行速度

    引用做函數返回值

    在了解引用做返回值時,我們還是得先了解傳值返回和傳引用返回的區別。其實原理和上面大致相同。

    1.傳值返回

    C++引用怎么使用及底層原理是什么

    C++引用怎么使用及底層原理是什么

    在返回c的時候,返回的不是c的本體,而是將c拷貝在一塊臨時空間里,所以返回的其實是這塊臨時空間。然后ret再次拷貝一個和這塊臨時空間一樣數據的空間。

    這塊有點像俄羅斯套娃,需要多畫圖理解。我一開始也有點懵逼。多畫圖就清晰了。

    但是問題又來了,這塊臨時拷貝空間又存儲在哪里呢?

    當c比較小的時候(4字節或者8字節),一般是存儲在寄存器中。

    當c比較大的時候,臨時變量放在該函數的棧幀上面。

    接下來我們通過觀察代碼的反匯編進行證明:

    C++引用怎么使用及底層原理是什么

    分析這段代碼的匯編,在進入add函數以后,先是將a的值給了eax,然后將b的值加上a,接著將eax里的值給了c。最后對c進行返回,在返回c的時候生成一個臨時拷貝,c將自己的值又給到了寄存器eax中。

    C++引用怎么使用及底層原理是什么

    最后回到主函數,eax將值給了ret。

    傳引用返回

    C++引用怎么使用及底層原理是什么

    這里進行的是傳引用返回,也就是說ret其實就是c的別名。傳引用返回,返回的就是本體,而不是拷貝。因為這里c是一個局部變量,在函數結束以后,棧幀被銷毀,局部變量的空間被系統回收了。這時ret再去訪問c的內容就可能造成非法訪問,并且c的值可能已經被修改了。

    形象的來說:就是你原先買了一個房子,后面你又將其賣給了別人,后面你想再次進入這個房子,但是這間房子已經不屬于你了,你進房子的操作就屬于非法訪問了。

    所以,傳引用返回時,返回的對象不能是出函數就被系統回收的。也就是說返回的變量不能是一個局部變量。

    引用的權限

    1.引用的權限可以縮小

    int main() {
    int a = 10;
    const int &b = a;//權限的縮小
    }

    這里變量a是可讀可寫的,而b是a的引用,b只能對a這塊內存空間進行讀取,不能進行修改,這就是權限的縮小,這在C++中是可以的。

    2.引用的權限不能放大

    int main() {
    const int a = 10;
    int &b = a;//權限的縮小
    }

    這里變量a指向的空間是只能讀取的,不能進行修改,而a的引用b,是可以對a指向的這塊空間進行修改的,使得權限得到了放大,這種語法在C++中是錯誤的。

    總結:引用可以進行權限的縮小,但是不能進行權限的放大

    引用經典筆試題

    下圖中的代碼(1)和(2)是否能夠正常運行?

    double d=11.1;
    int a=d;(1)
    int &ret=d;(2)

    答案:(1)可以運行通過,(2)不行。

    代碼(1)是普通的隱式類型轉換。

    而在了解代碼(2)的錯誤原因之前,我們需要回顧一些知識:

    產生臨時變量的情況

    1.類型轉換

    double d=11.1;

    int a=d;

    d的類型是double,a的類型是int,類型不同,正如下圖所示,在發生隱式類型轉換的時候,需要將d的值存到一個int類型的臨時變量里,然后將這個臨時變量的值賦予給a。

    C++引用怎么使用及底層原理是什么

    2.整形提升

    int a=10

    char c=‘b’;

    if(a>c){

    }

    這里并不是拿c直接和a進行比較,而是將c賦值到一個int的臨時變量里,通過這個臨時變量去和a進行比較。

    關于右值

    結論:右值是具有常性的,是不可修改的。

    這里的右值不能通過字面意思(處于式子右邊的值)進行理解,以下的幾種情況一般都是屬于右值。

    1.表達式的計算結果: 如:5+3=8,這里的8就是右值。

    2.常量:如a=5,這里的5就是右值。

    3.一些隱式類型轉換產生的臨時變量。如

    int a;

    double d;

    d=a;

    這里隱式類型轉換產生的臨時變量也是一種右值。

    在明白了這些基礎原理以后,我們開始學習為什么代碼int &ret=d;(2)是錯誤的。

    這里引用的變量其實是一塊臨時空間,而臨時空間是右值是不能修改的,這種引用的方式本質上其實就是權限的放大,因此編譯不能通過。

    C++引用怎么使用及底層原理是什么

    引用的底層原理

    int main() {
    int a;
    int &b = a;
    int *p = &a;
    }

    這里通過調試模式觀看這段代碼的反匯編。

    C++引用怎么使用及底層原理是什么

    這里的lea是取地址的意思。 從匯編代碼可以看出,在底成實現的時候,引用和指針的實現方式是一樣的,所以說: 引用的底層是通過指針實現的

    “C++引用怎么使用及底層原理是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    c++
    AI

    信丰县| 桑植县| 祁阳县| 类乌齐县| 青州市| 含山县| 宁波市| 枞阳县| 井冈山市| 四子王旗| 福贡县| 邻水| 西乌珠穆沁旗| 崇左市| 阿鲁科尔沁旗| 武强县| 馆陶县| 五华县| 磴口县| 宜黄县| 兴文县| 西藏| 东光县| 即墨市| 华阴市| 台中市| 西丰县| 江都市| 葫芦岛市| 淄博市| 福清市| 南陵县| 长岭县| 毕节市| 曲水县| 揭东县| 全南县| 宕昌县| 资兴市| 和林格尔县| 奈曼旗|