參考資料:
1、搜狗百科:
2、3、
1、c++引用(c++ reference)是對c語言的重要擴充,,引用的表示方法與定義指標相似,用&代替了*。
2、引用的概念及定義:
引用宣告的方法:型別識別符號& 引用名 = 目標變數名;或 型別識別符號 &引用名 = 目標變數名;(兩者的區別於指標中的類似)
例如:int a;int& b = a;
說明(1)&在引用中不是求位址運算,而是起到標示作用;
(2)型別識別符號是目標變數的型別,例如int
(3)(很重要)宣告引用時,必須同時對其進行初始化。如指標中,在使用指標前,一定要初始化指標(告訴指標的位址)
(4)引用宣告完畢後,相當於目標變數有兩個名稱,即該目標原名稱和引用名,一定不能再把該引用名作為其他變數的名稱
a為原名稱,b為目標引用名, 給b賦值:b=1等價於a=1.
(5)引用本身不佔記憶體,系統也不給引用分配記憶體。因為宣告乙個引用不是新定義乙個變數,它只辨識該引用是目標變數名的乙個別名,它本身不是一種資料型別。
(6)不能建立引用的陣列,因為陣列是乙個由若干個元素組成的集合,所以無法建立乙個由引用組成的集合。但是可以建立陣列的引用:
例如:const int (&ref) = ;//為什麼加上const?因為 此時四個字面值的陣列,是保持在**裡唯讀的屬性,如果不加,則會編譯錯誤,而且ref的複製也不會成功。
引用不產生物件的副本,僅僅是物件的同義詞。因此引用在定義時需要馬上被初始化,因為它必須是某個東西的同義詞,不能先定義乙個引用後才初始化。
3、引用的作用:
(1)傳遞可變引數
傳統的c,函式在呼叫時引數是通過值來傳遞的,這就是說:函式的引數不具備返回值的能力,因此在傳統的c中,如果函式的引數具有返回的能力往往是通過指標來實現的。
voidswapint(int&a,int&b)
//呼叫該函式的c++方法為:swapint(x,y); c++自動把x,y的位址作為
引數傳遞
給swapint函式。
(2)給函式傳遞大型物件
當大型物件被傳遞給函式是,使用引用引數可以使引數傳遞效率得到提高,因為引用並不產生物件的副本,也就是引數傳遞是,物件無須複製。
///過載運算子不能對指標單獨操作,我們必須把運算數宣告為 set 型別而不是 set *
4、引用作為返回值:
要以引用返回函式值,則函式定義時要按以下格式:
型別識別符號 &函式名(形參列表及型別說明)
說明:(1)以引用返回函式值,定義函式時需要在函式名前加&
(2)用引用返回乙個函式值的最大好處是,在記憶體中不產生被返回值的副本。
(3)不能返回區域性變數的引用。這條可以參照effective c++[1]的item 31。主要原因是區域性變數會在函式返回後被銷毀,因此被返回的引用就成為了'無所指'的引用,程式會進入未知狀態。
(4)不能返回函式內部new分配的記憶體的引用。這條可以參照effective c++[1]的item 31。雖然不存在區域性變數的被動銷毀問題,可對於這種情況(返回函式內部new分配記憶體的引用),又面臨其它尷尬局面。例如,被函式返回的引用只是作為乙個臨時變數出現,而沒有被賦予乙個實際的變數,那麼這個引用所指向的空間(由new分配)就無法釋放,造成memory leak。
(5)可以返回類成員的引用,但最好是const。這條原則可以參照effective c++[1]的item 30。主要原因是當物件的屬性是與某種業務規則(business rule)相關聯的時候,其賦值常常與某些其它屬性或者物件的狀態有關,因此有必要將賦值操作封裝在乙個業務規則當中。如果其它物件可以獲得該屬性的非常量引用(或指標),那麼對該屬性的單純賦值就會破壞業務規則的完整性。
(6)引用與一些操作符的過載:
流操作符《和》,這兩個操作符常常希望被連續使用,例如:cout << 'hello' << endl; 因此這兩個操作符的返回值應該是乙個仍然支援這兩個操作符的流引用。可選的其它方案包括:返回乙個流物件和返回乙個流物件指標。但是對於返回乙個流物件,程式必須重新(拷貝)構造乙個新的流物件,也就是說,連續的兩個《操作符實際上是針對不同物件的!這無法讓人接受。對於返回乙個流指標則不能連續使用《操作符。因此,返回乙個流物件引用是惟一選擇。這個唯一選擇很關鍵,它說明了引用的重要性以及無可替代性,也許這就是c++語言中引入引用這個概念的原因吧。 賦值操作符=。這個操作符象流操作符一樣,是可以連續使用的,例如:x = j = 10;或者(x=10)=100;賦值操作符的返回值必須是乙個左值,以便可以被繼續賦值。因此引用成了這個操作符的惟一返回值選擇。
(7)在另外的一些操作符中,卻千萬不能返回引用:
+-*/ 四則運算符。它們不能返回引用,effective c++[1]的item23詳細的討論了這個問題。主要原因是這四個操作符沒有side effect,因此,它們必須構造乙個物件作為返回值,可選的方案包括:返回乙個物件、返回乙個區域性變數的引用,返回乙個new分配的物件的引用、返回乙個靜態物件引用。根據前面提到的引用作為返回值的三個規則,第2、3兩個方案都被否決了。靜態物件的引用又因為((a+b) == (c+d))會永遠為true而導致錯誤。所以可選的只剩下返回乙個物件了。
5、常引用和引用多型
(1)常引用宣告方式:const 型別識別符號&引用名=目標變數名;
用這種方式宣告的引用,不能通過引用對目標變數的值進行修改,從而使引用的目標成為const,達到了引用的安全性。引用型引數應該在能被定義為const的情況下,盡量定義為const 。
(2)引用是除指標外另乙個可以產生多型效果的手段。這意味著,乙個基類的引用可以指向它的
派生類例項。
【例】:
class a;
class b:public a;
b b;
a &ref = b; // 用派生類物件初始化基類物件的引用
ref 只能用來訪問派生類物件中從基類繼承下來的成員,是基類引用指向派生類。如果a類中定義有虛函式,並且在b類中重寫了這個虛函式,就可以通過ref產生多型效果。
引用總結:
(1)在引用的使用中,單純給某個變數取個別名是毫無意義的,引用的目的主要用於在函式引數傳遞中,解決大塊資料或物件的傳遞效率和空間不如意的問題。
(2)用引用傳遞函式的引數,能保證引數傳遞中不產生副本,提高傳遞的效率,且通過const的使用,保證了引用傳遞的安全性。
(3)引用與指標的區別是,指標通過某個指標變數指向乙個物件後,對它所指向的變數間接操作。程式中使用指標,程式的可讀性差;而引用本身就是目標變數的別名,對引用的操作就是對目標變數的操作。
(4)使用引用的時機。流操作符《和》、賦值操作符=的返回值、拷貝建構函式的引數、賦值操作符=的引數、其它情況都推薦使用引用。
C 學習(三) 引用
為了說明c 中引用這個概念引入的意義,我們不妨從乙個最基礎的c語言交換兩個變數的值的函式說起 swap int a,int b 呼叫時,使用如下語句 swap a,b 這裡,傳遞的是變數a和b的位址,我們要交換a和b的值,函式卻用的是a和b的位址作為引數,感覺沒有那麼直觀形象。c 引入了 引用 這個...
C 學習(6) 引用
作用 給變數起別名 語法 資料型別 別名 原名 includeusing namespace std int main 引用一旦初始化,就不可以更改了 作用 函式傳參時,可以利用引用的技術讓形參修飾實參 優點 可以簡化指標修改實參 includeusing namespace std 交換函式 1....
C 學習筆記(二)引用與指標
一.引用和指標的異同 1.指標在定義時,可以不初始化,引用在定義時必須初始化 2.指標變數指向的位址可以根據需要動態修改,引用只要和某個變數繫結後就不能改變。3.指標本身需要占用4個位元組存放空間,而引用本身不要不用分配記憶體空間。4.使用sizeof求指標變數的大小總是4個位元組,表示位址所佔的空...