C++引用的意義與引用的本質

來源:互聯網
上載者:User

1、引用的意義

引用作為變數別名而存在,因此在一些場合可以替代指標,引用相對於指標來說具有更好的可讀性和實用性

// swap函數的實現對比void swap(int& a, int& b){    int t = a;    a = b;    b = t;}void swap(int* a, int* b){    int t = *a;    *a = *b;    *b = t;}
注意:

函數中的引用形參不需要進行初始化,初始化是在調用的時候完成的

2、特殊的引用

const引用

在C++中可以聲明const引用,具體用法如下:

const Type& name = var;

const引用讓變數擁有唯讀屬性,這個唯讀屬性是針對當前的這個別名,變數是可以通過其它方式進行修改

int a = 4;              // a是一個變數const int  & b = a;     // b是a的一個引用,但是b具有唯讀屬性int * p = (int *)&b;    // p = &ab = 5;     // err, 引用b 被const修飾,b是一個唯讀變數a = 6;     // okprintf("a = %d\n", a);*p = 5;    // okprintf("a = %d\n", a);

當使用常量對const引用進行初始化時,C++編譯器會為常量值分配空間,並將引用名作為這段空間的別名

#include <stdio.h>void Example(){    printf("Example:\n");      int a = 4;    const int& b = a;    int* p = (int*)&b;      //b = 5;    // b      *p = 5;       printf("a = %d\n", a);    printf("b = %d\n", b);}void Demo(){    printf("Demo:\n");      const int& c = 1;    int* p = (int*)&c;       //c = 5;    *p = 5;    printf("c = %d\n", c);}int main(int argc, char *argv[]){    Example();     printf("\n");      Demo();        return 0;}
結論:

使用常量對const引用初始化後將產生一個唯讀變數

問題:引用有自己的儲存空間嗎?

struct TRef{    char& r;}printf("sizeof(TRef) = %d\n, sizeof(TRef));

驗證程式:

#include <stdio.h>struct TRef{    char& r;        // 字元類型引用};int main(int argc, char *argv[]){     char c = 'c';    char & rc = c;    TRef ref = { c }; // 用C進行初始化, TRef.r 就是 c的別名了        printf("sizeof(char&) = %d\n", sizeof(char&));     // char引用的大小,引用即變數本身,求所對應的變數本身的大小,即sizeof(char) = 1    printf("sizeof(rc) = %d\n", sizeof(rc));        // rc是一個引用,即sizeof(c) = 1        printf("sizeof(TRef) = %d\n", sizeof(TRef));    // sizeof(TRef) = 4    printf("sizeof(ref.r) = %d\n", sizeof(ref.r));  // TRef.r是 c的別名,sizeof(c) = 1    // sizeof(TRef) = 4    // 指標變數本身也是佔4個位元組    // 引用和指標的關係        return 0;}

3、引用的本質

引用在C++中的內部實現是一個 指標常量

注意:

1、C++編譯器在編譯過程中用 指標常量 作為引用的內部實現,因此引用所佔用的空間大小於指標相同

2、從使用的角度,引用只是一個別名,C++為了使用性而隱藏了引用的儲存空間這一細節。

#include <stdio.h>struct TRef{    char* before;     // 4位元組    char& ref;        // 4位元組    char* after;    // 4位元組};int main(int argc, char* argv[]){    char a = 'a';    char& b = a;    char c = 'c';    TRef r = {&a, b, &c};    printf("sizeof(r) = %d\n", sizeof(r));    // sizeof(r) = 12    printf("sizeof(r.before) = %d\n", sizeof(r.before)); // sizeof(r.before) = 4    printf("sizeof(r.after) = %d\n", sizeof(r.after));   // sizeof(r.after) = 4    printf("&r.before = %p\n", &r.before);    // &r.before = 0xbuf8a300c    printf("&r.after = %p\n", &r.after);    // &r.after  = 0xbuf8a3014    /*     0xbuf8a3014 - 0xbuf8a300c = 8     before佔了4個位元組,所以ref也是佔4個位元組    */    return 0;}

引用的意義:

C++中的引用旨在大多數的情況下替代指標

  • 功能性:可以滿足多數需要使用指標的場合

  • 安全性:可以避開由於指標操作不當帶來的記憶體錯誤

  • 操作性:簡單易用,又不失功能強大

但是

引用可以在大多數情況下避免記憶體的錯誤,函數返回局部變數的引用,就沒法避免了

#include <stdio.h>int& demo(){    int d = 0;        printf("demo: d = %d\n", d);        return d;    // 實際上是返回了局部變數的地址,局部變數函數結束就銷毀了,返回錯誤}int& func(){    static int s = 0;        printf("func: s = %d\n", s);        return s;    // 返回靜態局部變數的地址,靜態局部變數儲存在全域區,函數結束生命週期還在,返回成功}int main(int argc, char* argv[]){    int& rd = demo();    // rd 成為demo裡面返回的局部變數d的別名,出現警告,但是通過編譯    int& rs = func();    // rs 成為靜態局部變數 s 的別名        printf("\n");    printf("main: rd = %d\n", rd);    // rd = 13209588,rd代表的是一個不存在的變數,現在是一個野指標    printf("main: rs = %d\n", rs);    // rs = 0    printf("\n");        rd = 10;    rs = 11;        // 通過rs改變了靜態局部變數s的值        demo();            // d = 10    func();            // s = 11        printf("\n");    printf("main: rd = %d\n", rd);    // rd = 13209588    printf("main: rs = %d\n", rs);    // rs = 11    printf("\n");        return 0;}

4、小結

引用作為變數別名而存在旨在代替指標

const引用可以使得變數具有唯讀屬性

引用在編譯器內部使用指標常量實現

引用的最終本質為指標

引用可以儘可能地避開記憶體錯誤

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.