最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++詳細分析引用的使用及其底層原理

 更新時間:2022年04月24日 11:25:48   作者:Fengliguantou@  
引用是C++一個很重要的特性,顧名思義是某一個變量或對象的別名,對引用的操作與對其所綁定的變量或對象的操作完全等價,這篇文章主要給大家總結介紹了C++中引用的相關知識點,需要的朋友可以參考下

引用

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

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

引用的注意事項

  • 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三個變量指向的都是同一塊內(nèi)存空間。

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

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

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

引用做參數(shù)

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

1.參數(shù)傳值

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

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

2.引用傳參

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

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

實參傳值和傳引用的優(yōu)劣

1.實參傳值:

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

優(yōu)點:因為形參是實參的拷貝,所以形參的操作不會影響實參,可以防止實參數(shù)據(jù)遭到污染。

2.實參傳引用

缺點:形參的操作對實參會產(chǎn)生影響,形參的錯誤操作會讓實參數(shù)據(jù)遭到修改。

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

引用做函數(shù)返回值

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

1.傳值返回

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

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

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

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

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

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

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

最后回到主函數(shù),eax將值給了ret。

傳引用返回

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

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

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

引用的權限

1.引用的權限可以縮小

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

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

2.引用的權限不能放大

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

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

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

引用經(jīng)典筆試題

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

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

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

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

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

產(chǎn)生臨時變量的情況

1.類型轉換

double d=11.1;

int a=d;

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

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.一些隱式類型轉換產(chǎn)生的臨時變量。如

int a;

double d;

d=a;

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

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

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

引用的底層原理

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

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

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

到此這篇關于C++詳細分析引用的使用及其底層原理的文章就介紹到這了,更多相關C++引用的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++/Php/Python/Shell 程序按行讀取文件或者控制臺的實現(xiàn)

    C++/Php/Python/Shell 程序按行讀取文件或者控制臺的實現(xiàn)

    下面小編就為大家?guī)硪黄狢++/Php/Python/Shell 程序按行讀取文件或者控制臺的實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 基于Turbo C(V2.0)編譯錯誤信息的詳細介紹

    基于Turbo C(V2.0)編譯錯誤信息的詳細介紹

    本篇文章對Turbo C(V2.0)編譯的錯誤信息進行了詳細的介紹。需要的朋友參考下
    2013-05-05
  • C++?和?C#?中的?lambda的方法技巧

    C++?和?C#?中的?lambda的方法技巧

    這篇文章主要介紹了C++?和?C#?中的?lambda的方法技巧,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-06-06
  • C++簡單又輕松的講解類和對象中友元函數(shù)

    C++簡單又輕松的講解類和對象中友元函數(shù)

    采用類的機制后實現(xiàn)了數(shù)據(jù)的隱藏與封裝,類的數(shù)據(jù)成員一般定義為私有成員,成員函數(shù)一般定義為公有的,依此提供類與外界間的通信接口。但是,有時需要定義一些函數(shù),這些函數(shù)不是類的一部分,但又需要頻繁地訪問類的數(shù)據(jù)成員,這時可以將這些函數(shù)定義為該類的友元函數(shù)
    2022-06-06
  • C++將字符串格式化的幾種方式總結

    C++將字符串格式化的幾種方式總結

    這篇文章主要介紹了C++將字符串格式化的幾種方式總結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C++實現(xiàn)雙向鏈表

    C++實現(xiàn)雙向鏈表

    這篇文章主要為大家詳細介紹了C++實現(xiàn)雙向鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • c++模板自定義數(shù)組

    c++模板自定義數(shù)組

    這篇文章主要介紹了c++模板自定義數(shù)組,通過制造通用模板,創(chuàng)建自定義的數(shù)組展開文章相關內(nèi)容,具有一的參考價值,需要的小伙伴可以參考一下
    2022-03-03
  • C++實現(xiàn)LeetCode(9.驗證回文數(shù)字)

    C++實現(xiàn)LeetCode(9.驗證回文數(shù)字)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(9.驗證回文數(shù)字),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 利用上下文屬性將?C++?對象嵌入?QML?里

    利用上下文屬性將?C++?對象嵌入?QML?里

    這篇文章主要介紹了利用上下文屬性將?C++?對象嵌入?QML里,將?QML?對象加載到?C++?應用程序中時,直接嵌入一些可在?QML?代碼中使用的?C++?數(shù)據(jù)會很有用。例如,這使得在嵌入對象上調用?C++?方法或使用?C++?對象實例作為?QML?視圖的數(shù)據(jù)模型成為可能,下面一起來學習該內(nèi)容吧
    2021-12-12
  • C++常量詳解一(常量指針與常量引用的初始化)

    C++常量詳解一(常量指針與常量引用的初始化)

    這篇文章主要介紹了C++常量詳解一(常量指針與常量引用的初始化),需要的朋友可以參考下
    2017-06-06

最新評論

宜黄县| 姜堰市| 左云县| 郴州市| 旬阳县| 英超| 温宿县| 林芝县| 平安县| 左云县| 类乌齐县| 仁怀市| 齐河县| 沁阳市| 罗定市| 凭祥市| 巴南区| 英德市| 同江市| 绥江县| 盱眙县| 龙里县| 乌审旗| 蒲江县| 报价| 长汀县| 思茅市| 兴安盟| 湘阴县| 诏安县| 宾阳县| 阿克苏市| 北京市| 新蔡县| 永胜县| 万全县| 诏安县| 祁东县| 忻州市| 固镇县| 庆云县|