很多人把指針和引用看成兩個完全不同的東西,引用只是個別名,不占用實際內存,只不過操作起來有點像指針.實際上引用就是一個指針,只不過是個特殊的指針,編譯器對它做了些特殊的處理.它也占用內存.但由於編譯器做了特殊處理,你不能用&去取址,用sizeof得到的值也不會是4或者8,而是它引用的對象的size大小.
其實我們想想也知道,如果引用真只是個別名,沒啥其他意思.那真是叫飽了撐著搞個引用出來啊.直接用本來的名字不就行了,為啥用它的別名啊.所以引用實際上也只就是保存一個地址值在那.
要區分指針和引用,先說下常量指針和指針常量兩個概念.
常量指針和指針常量
覺得看著這兩術語非常讓人暈,非常容易混淆.如果不去管它們,直接看英語就一目了然了.
常量指針(pointer to constant)
我覺得翻譯成常量指針不太好,應該說指向常量的指針,雖然多了幾個字但意思清晰了很多.不過其實也還不夠准確的.先舉個簡單的例子吧.
const int num = 88;
const int* p = # //p就是一個常量指針,它指向常量num.常量指針非得指向常量嗎?不一定
int no = 99;
const int* pp = &no; //pp也是個常量指針,但不指向常量.
常量指針只是表示指針指向的對象的值不能通過指針的方式去改變.
所以*p = 123和*pp = 123這樣去賦值都不行.但no = 123這樣賦值卻可以.
指針常量(constant pointer)
其實我覺得這裡翻譯成常量指針才更好點,constant是在前面做修飾語的.
int num = 44;
int* const pp = # //這樣寫也可以int const* pp = #
指針常量表示指針指向了某個地方之後不能再指向其他地方了.
所以如果int no = 55;
pp = &no; //這裡就會出錯,pp不能再指向no了
我們平時定義啥常量時都是要馬上初始化才行的.指針常量也一樣.
int* pp; //這樣是可以
int* const pp; //這樣就不行了.不過你可以賦空值.比如int* const pp = 0;
我們只要看const是位於類型關鍵字左邊還是右邊.比如上面在int左邊則是修飾指向的變量,如果在int右邊則是修飾指針本身.
如果兩個const同時用const int *const pp = #就是常量指針常量, 這名字真是超級難聽.覺得還是叫指向常量的常量指針好點.
引用是特殊的指針常量
說了上面兩個概念就很容易理解引用了.
引用實際上就是個指針常量(constant poniter).只不過是個特殊的指針常量.首先使用時語法就不一樣
int num = 22;
int & rNum = num; //如果是const int num;那麼引用就是const int& rNum = num;
另外就是引用時指向的對象必須是胡有效存在的,不能指向空的引用.除此之外和指針常量沒啥區別了.一個樣.據說用反編譯看匯編代碼,引用的最終實現就跟指針一樣的.不過我還真沒去驗證過.
由於編譯器做了特殊處理,引用就直接用名字,不用前面再加個星星*去解引用.這樣用起來方便多了.所以凡是用到指針常量的地方都差不多可以用引用來代替了.