[8.1] 什麼是引用?
一個對象的別名(一個替換的名字)叫引用
引用經常被用來做在函數參數的引用傳遞中
void swap(int& i,int& j)
{
int tmp=i;
i=j;
j=tmp;
}
int main()
{
int x,y;
swap(x,y);
}
這裏i和j是main是函數x和y的引用。換句話說,i就是x---不是說是x的一個指針或說是x的拷貝,而是x本身,你對i做的一切都相當於直接對x進行操作,反之也是一樣的。
這樣就是你作爲一個程序對於引用應該瞭解的。現在,冒着通過給你一個不同的視角來你感到迷惑的危險,解釋一下引用是如何實現的。在最底層中,對象x的一個引用i是對象x的機器地址。但是如果程序員執行i++的時候,編譯器會生成讓x自增的代碼。特別是,編譯器用來查找x的的地址位並沒有發生改變。一個C程序員會把這個想象爲C中的指針調用。換句話說,C程序員會把i想象爲*p的一個,這裏p是指向x的一個指針(例如,編譯器會自動地反引用底層的指什;i++就被換爲成了(*p)++;i=7會自動被成*p=7)。
注意 : 甚至引用經常是通過使用底層的彙編語言來實現的,請不要把引用想象成一個對象的一個長相奇怪的指針,一個引用就是一個對象。它不是指向對象的指針,也不是對象一個拷貝。它就是那個對象。
[8.2] 如果對一個引用賦值會發生什麼呢?
你可以改變一個引用體(referent)的狀態(引用體referent就是引用引到的那個對象)
記住: 引用就是引用體,如果改變引用就可以直接改變引用體的狀態。用編譯器編寫者的術語來叫,一個引用就是一個"左值"("lvalue")(就是可以出現在的賦值符左端的東西)
[8.3] 當你返回一個引用的時候會發生什麼?
函數調用可以出現在賦值運算符的左端。
這樣的能力開始可能會比較奇怪。例如,沒有人會覺得f()=7有意義。但是,如果a是一個對象數組裏的一個對象,很多人都會覺得a[i]=7是有意義的甚至a[i]其實是一個僞裝起來的函數調用(它就是數據的[]調用: Array::operator[](int),它就是數組類的一個子腳本的運算符).
class Array {
public:
int size() const;
float& operator[](int index);
//..
};
int main()
{
Array a;
for(int i=0;i a[i]=7; //這一行就調用了Array::operator[](int)
}
[8.4] 如何讓一個引用重新引用到另外一個對象上?
這是不可能的
與指針不一樣,如果一個引用被綁定到對象中,它就可以重賦值到另一個對象中。如果引用對象本身不是一個對象(它沒有標誌信息,取得引用的地址就得到了引用體的地址;記住,引用就是引用體自己)
在這種意義下,一個引用與一個常指針,比如說int* const p是相似的(與一個像const int* p的指向常數的指針相反).儘管有這些相似性,請不要把引用與指針相混,它們是完全不一樣的東西。
[8.5] 我什麼時候用引用,什麼時候用指針呢?
只要能用就用引用,不得以的情況下再用指針。
當你不需要進行重賦值的時候,使用通常是比指針更好的解決方法。這通常就是說,引用是一個類的公有成員接口最有用的部分。引用經常顯示一個對象的外表,而指針通常是內部的內容。
[8.4] 如何讓一個引用重新引用到另外一個對象上?
這是不可能的
你不能把引用體從引用身上分離出來
與指針不一樣,如果一個引用被綁定到對象中,它就可以重賦值到另一個對象中。如果引用對象本身不是一個對象(它沒有標誌信息,取得引用的地址就得到了引用體的地址;記住,引用就是引用體自己)
在這種意義下,一個引用與一個常指針,比如說int* const p是相似的(與一個像const int* p的指向常數的指針相反).儘管有這些相似性,請不要把引用與指針相混,它們是完全不一樣的東西。
[8.5] 我什麼時候用引用,什麼時候用指針呢?
只要能用就用引用,不得以的情況下再用指針。
當你不需要進行重賦值的時候,使用通常是比指針更好的解決方法。這通常就是說,引用是一個類的公有成員接口最有用的部分。引用經常顯示一個對象的外表,而指針通常是內部的內容。
上面所講的一種例外情況是當一個函數參數或是返回值需要一個"守衛"引用。它經常是通過返回或接受一個指針來實現,這樣被認爲是最佳的實現方式,那麼給一個空指針就會造成麻煩(引用總是與對象相關聯的,而不會是一個空的指針).
注意: 一個老的C程序員有時候有時候不喜歡引用因爲它提供了一個在調用代碼中已清晰說明了的引用方法。然而在有一些C++編程經驗之後,你可以很快認識到這是一種信息隱藏的方法,它是一種財產,而不是一種責任。比如說,程序員應該針對問題寫代碼,而不是針對機器語言寫代碼。
[8.4] 如何讓一個引用重新引用到另外一個對象上?
這是不可能的
你不能把引用體從引用身上分離出來
與指針不一樣,如果一個引用被綁定到對象中,它就可以重賦值到另一個對象中。如果引用對象本身不是一個對象(它沒有標誌信息,取得引用的地址就得到了引用體的地址;記住,引用就是引用體自己)
在這種意義下,一個引用與一個常指針,比如說int* const p是相似的(與一個像const int* p的指向常數的指針相反).儘管有這些相似性,請不要把引用與指針相混,它們是完全不一樣的東西。
[8.5] 我什麼時候用引用,什麼時候用指針呢?
只要能用就用引用,不得以的情況下再用指針。
當你不需要進行重賦值的時候,使用通常是比指針更好的解決方法。這通常就是說,引用是一個類的公有成員接口最有用的部分。引用經常顯示一個對象的外表,而指針通常是內部的內容。
上面所講的一種例外情況是當一個函數參數或是返回值需要一個"守衛"引用。它經常是通過返回或接受一個指針來實現,這樣被認爲是最佳的實現方式,那麼給一個空指針就會造成麻煩(引用總是與對象相關聯的,而不會是一個空的指針).
注意: 一個老的C程序員有時候有時候不喜歡引用因爲它提供了一個在調用代碼中已清晰說明了的引用方法。然而在有一些C++編程經驗之後,你可以很快認識到這是一種信息隱藏的方法,它是一種財產,而不是一種責任。比如說,程序員應該針對問題寫代碼,而不是針對機器語言寫代碼。