linux c/c++ 學習總結(6)-- 對引用的理解

爲什麼要在c++中引入“引用?
按照c++之父斯特勞斯特魯普的說法是:(以下內容摘抄自斯特勞斯特魯普的個人網站)

C++ 的指針繼承於 C,若要移除指針,勢必造成嚴重的兼容性問題。引用有幾方面的用處,但我在 C++ 中引入它的主要目的是爲了支持運算符重載。例如:

 void f1(const complex* x, const complex* y)    // 沒有引用
{
    complex z = *x+*y;  // 難看
    // ...
}

void f2(const complex& x, const complex& y) // 使用引用
 {
    complex z = x+y;    // 看起來不錯
    // ...
}

我們在學習c++過程中,會覺得引用是一個非常簡單好用的東西,但仔細體會會發現它的一些特性不太好捉摸,下面總結下:

引用的本質是什麼?

我覺得要說清楚這個話題需要對引用有2個方面的理解,一個是“單純的c++規範”層面的理解,另一個是各個編譯器廠家如何“實現引用”的層面來理解。
1. “單純的c++規範”層面:引用是一個具名變量的別名,這個所有c++書籍上都會介紹的,但這句背後的含義是什麼呢?答案是”引用不是對象”!!!對象是什麼呢?你可能會說:對象就是“new出來的東西”。但嚴格來說應當是:

對象是帶有一些性質的儲存區域,這些性質包括:大小(sizeof),內存對齊,生命週期,連接性,類型,名字(new 出來的對象是不具名對象,沒有名字)。

在c++中有哪些地方能體現出來“引用不是對象”呢?看代碼:

int* arr1[10];    //指針數組,每個位置上放置一個指向int類型的指針
int& arr2[10];    //error,沒有這種寫法,沒有存放引用的數組,因爲引用不是對象

int& *p = NULL;   //error,沒用指向指針的引用

int && p;         //error,沒有指向應用的應用,這裏其實一個右值引用,p需要用一個臨時量初始化

這一層面的理解關鍵是知道:引用不是對象。
2. 編譯器如何“實現引用”:編譯器通過“自解引用的常量指針”來實現引用的效果。看代碼:

int num = 90int & r = num;   
//等價於 
int * const r = #  //這也是引用爲什麼要初始化的原因

cout<<r<<endl;   //輸出num
//等價於
cout<<*r<<endl;  

總結:引用需要理解到這兩個層面才能理解一些問題。
1. c++中爲什麼沒有“引用數組”,“指向引用的指針”,“指向引用的引用”,原因是“引用不是對象”。
2.不是說“引用不是對象嗎?” 爲什麼函數傳參時,以及函數的返回值可以引用?(函數也不是對象,因此函數傳參不能傳遞,函數的返回值也不能是函數,實際上傳遞的都是指向函數的指針)。這時應當把引用理解成“引用是一個const指針”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章