(搬家文) c++引用深入探討

來源:互聯網
上載者:User

(偶然翻起自己的舊博,忽然發現大三的時候寫的這篇文章,仔細看看覺得寫的還是那麼回事,所以趕緊搭救出來)

引用的聲明:   基本格式:參考型別 &引用名=被引用對象 

  1. &運算子:聲明運算子& 跟取地址運算子&和位異或運算子&沒有任何關係
  2. extern關鍵字:一般情況下 引用的聲明必須指定被引用對象 唯一的例外是使用extern關鍵字
  3. const關鍵字:一般情況下 被引用對象必須是有效左值對象 但是const關鍵字修飾的常參考型別允許被引用對象不是左值對象

引用的使用:引用可以被當作被引用對象的別名使用,單純的引用是無意義的,引用主要應用於四個方面:

  1. 函數參數:可修改的實參,高效的複雜物件傳遞方式
  2. 函數傳回值:不產生複製的傳回值,返回左實值型別的函數
  3. 運算子多載:為++ -- << >>等運算子提供了更貼近原意的重載方式
  4. 多態:代替指標使用,實現抽象類別的引用

 引用的深入探討:現在開始進入正題

    1.引用占記憶體空間嗎?

        如果引用只是一個別名的話 他不應該佔有記憶體空間 我用下面這段代碼來查看

 

代碼

#include <iostream>
using namespace std;
void fa(){
    int a[4];    
    cout<<a<<endl;
}
void fb(){
    int a[4];
    int &b=a[0];
    cout<<a<<endl;
    fa();
}
void fc(){
    int a[4];
    cout<<a<<endl;
    fb();
}
int main()
{
    fc();
    getchar();
    return 0;
}

 

 

這段代碼裡 我用了三個嵌套的函數調用 這樣 fa 和fc的棧段就把fb夾在了中間 fb的棧段大小變化的話 會導致fc中a的地址位移 但是並不是每個分配都會導致棧段增大的 所以應該先測試一下 確定a的合適大小 使得一旦聲明變數 b的棧段就增大。

把int &b=a[0];注釋掉的話 可以看到fc中輸出的地址變了 fb沒有變 那麼 引用b顯然佔據了記憶體空間 My Code在g++中編譯,結果也是g++的結果。

2.引用的值不可改變嗎?

一個已經初始化的參考型別對象 其引用的對象不可能被合法的改變。

前面一段代碼展示給我們 引用確實佔據了記憶體空間 ,了進一步瞭解其本質,我們必須獲得它的地址。&取地址操作符顯然是無法做到的 幾乎每個學c++的人都會嘗試用這種辦法去取參考型別的地址,但得到的都是被引用對象的地址。

還從前面的例子入手 fb中 a的地址沒有改變  fa中a的地址改變 那麼 int &b的分配應該在 二者之間 於是 最可能的位置就是a中的a[4]   但輸出之後我發現a[4]不是,因為數組a是跟棧逆向分配的 之後我試了這樣的代碼
void fb(){
    int a[4];
    int b=20;
    cout<<a[-1]<<endl;
    fa();
}

 在我的編譯器中 b跟a[-1]總是相等 於是 我把int b 替換成int &b=a[0]; ok 我發現它指向了一個貌似地址的東西。改變b的指向 發現a[-1]是隨之變化的 現在 我幾乎可以確定 a[-1]就是b了 再用一段這樣的代碼來檢驗
void fb(){
    int a[4]={1,2,3,4};
    int &b=a[0];
    a[-1]+=4;
    cout<<b<<","<<a[0]<<endl;
    fa();
}

引用真的是不可改變的嗎? 在這個例子中 我使b指向了a[1] 而不再是a[0]

3.引用和指標
從上面的例子看出 引用的內部實現和指標並無兩樣。如果參考其他語言的思想的話 可以得到結論:引用就是指標常量。 在c++中 引用在文法上與指標有著明顯的差異 但是 他們並沒有本質不同 引用是c++中實現的一種限制比較嚴格的常量指標 它在參與任何運算之前自動解引用。

在使用中 推薦盡量用引用代替指標,因為引用是一種比指標更安全的類型 並且有更清晰的語義(當然指標也有適合的語義)

4.其他語言
順便一提,在C家的其他語言中 引用幾乎被作為訪問對象的唯一手段

C++:有指標 所有運算子會解引用 所有對象不作為引用 傳遞參數和傳回值時如果不希望複製 則必須將形參指定為參考型別
C#: unsafe模式有指標 除了=之外的操作符會解引用 所有對象作為引用 傳遞參數和傳回值時如果希望複製 則必須顯式clone
Java:無指標 除了=之外的操作符會解引用 類似c#
javascript:無指標但是可以變通 除了=之外的操作符會解引用 沒有提供複製傳遞的方法(鬱悶)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.