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

解析C++引用

 更新時(shí)間:2021年06月09日 10:20:39   作者:lsgxeva  
引用是C++引入的新語(yǔ)言特性,是C++常用的一個(gè)重要內(nèi)容之一。在工作中發(fā)現(xiàn),許多人使用它僅僅是想當(dāng)然,在某些微妙的場(chǎng)合,很容易出錯(cuò),究其原由,大多因?yàn)闆]有搞清本源。在本篇中將對(duì)引用進(jìn)行詳細(xì)討論,希望對(duì)大家更好地理解和使用引用起到拋磚引玉的作用

引言

我選擇寫C++中的引用是因?yàn)槲腋杏X大多數(shù)人誤解了引用。而我之所以有這個(gè)感受是因?yàn)槲抑鞒诌^很多C++的面試,并且我很少?gòu)拿嬖囌咧械玫疥P(guān)于C++引用的正確答案。

那么c++中引用到底意味這什么呢?通常一個(gè)引用讓人想到是一個(gè)引用的變量的別名,而我討厭將c++中引用定義為變量的別名。這篇文章中,我將盡量解釋清楚,c++中根本就沒有什么叫做別名的東東。

背景

在c/c++中,訪問一個(gè)變量只能通過兩種方式被訪問,傳遞,或者查詢。這兩種方式是:

1.通過值訪問/傳遞變量

2.通過地址訪問/傳遞變量–這種方法就是指針

除此之外沒有第三種訪問和傳遞變量值的方法。引用變量也就是個(gè)指針變量,它也擁有內(nèi)存空間。最關(guān)鍵的是引用是一種會(huì)被編譯器自動(dòng)解引用的指針。很難相信么?

下面是一段使用引用的簡(jiǎn)單c++代碼

#include <iostream.h>  
int main()  
{  
    int i = 10;   // A simple integer variable  
    int &j = i;   // A Reference to the variable i  
    j++;   // Incrementing j will increment both i and j.  
    // check by printing values of i and j  
    cout<<  i  <<  j  <<endl; // should print 11 11  
    // Now try to print the address of both variables i and j  
    cout<<  &i  <<  &j  <<endl;  
    // surprisingly both print the same address and make us feel that they are  
    // alias to the same memory location.  
    // In example below we will see what is the reality  
    return 0;  
}   

引用其實(shí)就是c++中的常量指針。表達(dá)式int &i = j;將會(huì)被編譯器轉(zhuǎn)化成int *const i = &j;而引用之所以要初始化是因?yàn)閏onst類型變量必須初始化,這個(gè)指針也必須有所指。下面我們?cè)俅尉劢沟缴厦孢@段代碼,并使用編譯器的那套語(yǔ)法將引用替換掉。

#include <iostream.h>  
int main()  
{  
    int i = 10;            // A simple integer variable  
    int *const j = &i;     // A Reference to the variable i  
    (*j)++;                // Incrementing j. Since reference variables are   
                          // automatically dereferenced by compiler  
    // check by printing values of i and j  
    cout<<  i  <<  *j  <<endl; // should print 11 11  
    // A * is appended before j because it used to be reference variable  
    // and it should get automatically dereferenced.  
    return 0;  
}  

讀者一定很奇怪為什么我上面這段代碼會(huì)跳過打印地址這步。這里需要一些解釋。因?yàn)橐米兞繒r(shí)會(huì)被編譯器自動(dòng)解引用的,那么一個(gè)諸如cout << &j << endl;的語(yǔ)句,編譯器就會(huì)將其轉(zhuǎn)化成語(yǔ)句cout << &*j << endl;現(xiàn)在&*會(huì)相互抵消,這句話變的毫無(wú)意義,而cout打印的j值就是i的地址,因?yàn)槠涠x語(yǔ)句為int *const j = &i;

所以語(yǔ)句cout << &i << &j << endl;變成了cout << &i << &*j << endl;這兩種情況都是打印輸出i的地址。這就是當(dāng)我們打印普通變量和引用變量的時(shí)候會(huì)輸出相同地址的原因。

下面給出一段復(fù)雜一些的代碼,來(lái)看看引用在級(jí)聯(lián)(cascading)中是如何運(yùn)作的。

#include <iostream.h>  
int main()  
{  
    int i = 10; // A Simple Integer variable  
    int &j = i; // A Reference to the variable  
    // Now we can also create a reference to reference variable.   
    int &k = j; // A reference to a reference variable  
    // Similarly we can also create another reference to the reference variable k  
    int &l = k; // A reference to a reference to a reference variable.  
    // Now if we increment any one of them the effect will be visible on all the  
    // variables.  
    // First print original values  
    // The print should be 10,10,10,10  
    cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    // increment variable j  
    j++;   
    // The print should be 11,11,11,11  
    cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    // increment variable k  
    k++;  
    // The print should be 12,12,12,12  
    cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    // increment variable l  
    l++;  
    // The print should be 13,13,13,13  
    cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    return 0;  
}  

下面這段代碼是將上面代碼中的引用替換之后代碼,也就是說(shuō)明我們不依賴編譯器的自動(dòng)替換功能,手動(dòng)進(jìn)行替換也能達(dá)到相同的目標(biāo)。

#include <iostream.h>  
int main()  
{  
    int i = 10;         // A Simple Integer variable  
    int *const j = &i;     // A Reference to the variable  
    // The variable j will hold the address of i  
    // Now we can also create a reference to reference variable.   
    int *const k = &*j;     // A reference to a reference variable  
    // The variable k will also hold the address of i because j   
    // is a reference variable and   
    // it gets auto dereferenced. After & and * cancels each other   
    // k will hold the value of  
    // j which it nothing but address of i  
    // Similarly we can also create another reference to the reference variable k  
    int *const l = &*k;     // A reference to a reference to a reference variable.  
    // The variable l will also hold address of i because k holds address of i after  
    // & and * cancels each other.  
    // so we have seen that all the reference variable will actually holds the same  
    // variable address.  
    // Now if we increment any one of them the effect will be visible on all the  
    // variables.  
    // First print original values. The reference variables will have * prefixed because   
    // these variables gets automatically dereferenced.  
    // The print should be 10,10,10,10  
    cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    // increment variable j  
    (*j)++;   
    // The print should be 11,11,11,11  
    cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    // increment variable k  
    (*k)++;  
    // The print should be 12,12,12,12  
    cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    // increment variable l  
    (*l)++;  
    // The print should be 13,13,13,13  
    cout  <<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    return 0;  
}  

我們通過下面代碼可以證明c++的引用不是神馬別名,它也會(huì)占用內(nèi)存空間的。

#include <iostream.h>  
class Test  
{  
    int &i;   // int *const i;  
    int &j;   // int *const j;  
    int &k;   // int *const k;   
};  
int main()  
{      
    // This will print 12 i.e. size of 3 pointers  
    cout<<  "size of class Test = "  <<   sizeof(class Test)  <<endl;  
    return 0;  
}  

結(jié)論

我希望這篇文章能把c++引用的所有東東都解釋清楚,然而我要指出的是c++標(biāo)準(zhǔn)并沒有解釋編譯器如何實(shí)現(xiàn)引用的行為。所以實(shí)現(xiàn)取決于編譯器,而大多數(shù)情況下就是將引用實(shí)現(xiàn)為一個(gè)const指針。

引用支持c++虛函數(shù)機(jī)制的代碼

#include <iostream.h>  
class A  
{  
public:  
         virtual void print() { cout<<"A.."<<endl; }  
};  
class B : public A  
{  
public:  
         virtual void print() { cout<<"B.."<<endl; }  
};  
   
class C : public B  
{  
public:  
         virtual void print() { cout<<"C.."<<endl; }  
};  
int main()  
{  
         C c1;  
         A &a1 = c1;  
         a1.print(); // prints C  
         A a2 = c1;  
         a2.print(); // prints A  
         return 0;  
}  

上述代碼使用引用支持虛函數(shù)機(jī)制。如果引用僅僅是一個(gè)別名,那如何實(shí)現(xiàn)虛函數(shù)機(jī)制,而虛函數(shù)機(jī)制所需要的動(dòng)態(tài)信息只能通過指針才能實(shí)現(xiàn),所以更加說(shuō)明引用其實(shí)就是一個(gè)const指針。

以上就是解析C++引用的詳細(xì)內(nèi)容,更多關(guān)于C++引用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言運(yùn)算符的重載詳解

    C語(yǔ)言運(yùn)算符的重載詳解

    這篇文章主要為大家詳細(xì)介紹C語(yǔ)言運(yùn)算符的重載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng)

    C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++17新特性個(gè)人總結(jié)

    C++17新特性個(gè)人總結(jié)

    這篇文章主要介紹了C++17新特性個(gè)人總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目

    C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C語(yǔ)言之通訊錄的模擬實(shí)現(xiàn)代碼

    C語(yǔ)言之通訊錄的模擬實(shí)現(xiàn)代碼

    這篇文章主要介紹了C語(yǔ)言之通訊錄的模擬實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷程序

    C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷程序

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++進(jìn)程鏈接工具之通信器詳解

    C++進(jìn)程鏈接工具之通信器詳解

    本文主要介紹了C++通信器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-11-11
  • 使用Matlab制作大富翁小游戲的過程詳解

    使用Matlab制作大富翁小游戲的過程詳解

    大富翁大家都玩過,走到建筑的位置可以買地,第二圈走到買過的地可以升級(jí),別人經(jīng)過后需要付過路費(fèi),每次經(jīng)過起點(diǎn)都會(huì)獲得一定資金,玩到最后還沒破產(chǎn)的就是勝者,本文將制作一個(gè)Matlab版的大富翁小游戲,需要的可以參考一下
    2022-02-02
  • C++ 名稱空間詳情

    C++ 名稱空間詳情

    當(dāng)一個(gè)項(xiàng)目變得大型之后,我們會(huì)引入很多的庫(kù),這么一來(lái)兩個(gè)庫(kù)很可能會(huì)定義List、Tree、Node同名的類,編譯器要是不考慮這情況的話,程序員調(diào)用時(shí)就會(huì)出現(xiàn)沖突問題。C++提供了名稱空間工具,以更好的控制名稱的作用域,本文就來(lái)談?wù)凜++ 名稱空間,需要的朋友可以參考一下
    2021-09-09
  • opencv實(shí)現(xiàn)角點(diǎn)檢測(cè)

    opencv實(shí)現(xiàn)角點(diǎn)檢測(cè)

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)角點(diǎn)檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評(píng)論

龙川县| 镇康县| 察隅县| 隆林| 化德县| 鞍山市| 宁远县| 定兴县| 维西| 赫章县| 台南市| 台安县| 中卫市| 财经| 陇川县| 甘孜县| 横峰县| 济源市| 宜都市| 张家界市| 滦南县| 加查县| 珠海市| 湖州市| 沛县| 桐乡市| 榕江县| 宜章县| 宜兴市| 长子县| 布尔津县| 犍为县| 应用必备| 临沭县| 宁陕县| 张家川| 托克托县| 肥城市| 资溪县| 和林格尔县| 山东省|