經常c++程式設計師會提到「常量指標( const pointer )」, 其實他們想表達的意思往往是「指向常量的指標(pointer to const)」。 真不幸, 這是兩個完全不同的概念。
這裡一定要弄清楚t* pt = new t;
const t* pct = pt; //乙個指向常量的指標
t* const cpt = pt; //乙個常量指標
const
修飾符修飾的物件是 基礎型別還是指標修飾符*.
c++ 中對於指標修飾符*左側內容具有順序無關的語法特性更是加劇了這種混淆:
以上兩種方式宣告指向常量的指標具有相同的效果。const t *p1;
t const *p2;
出於習慣和對傳統的尊重,一般我們常使用第一種方式,但是許多c++專家推薦第二種形式。 理由是第二種形式不容易被誤解。 因為這種宣告可以倒過來讀,即const
修飾的是基礎型別t
,也即指向常量t
的指標。
這個時候只要看看t* pt = new t;
t const* pct =pt;
t* const cpt = pt;
const
前面是t
還是*
就知道const
修飾的物件了。
上面我們看到t* pt
是乙個普通的指向非常量的指標,它可以自動轉換為指向常量的指標t const* pct = pt
;
pointer
base typeptt
pctconst t
這是c語言本身的特性,而且理解起來也很直觀, 因為這種轉換不會帶來潛在的危險,那麼對於多級指標呢?
二級指標的情形比較複雜,讀起來也比較拗口。 考慮如下情形:
這種轉化是錯誤的, 為什麼呢?char* chr[max]; //chr 退化為乙個「指向非常量的指標」的指標
const
char **ppct = chr; //ppct是乙個「指向常量的指標」的指標
pointer
base type
chrchar*
ppct
const char*
假如我們將char* 和 const char* 分別看成乙個整體,
順便提一下下面這種轉換也是不對的:typedef
char* a;
typedef
const
char* b;
a* a = 0;
b* b = a; //這種轉換是兩個不相關的指標的轉換,是不對的
circle* c = new circle;
shape* s = c; //上行轉換沒問題
circle ** cc =&c;
shape **ss = cc; //這就錯了
const t* const cpct = pt;
大家看到第乙個const 顯然修飾 t, 第二個const 修飾的物件是*, 這樣cpct
既是乙個指向常量的指標又是乙個指標常量。
既然我們都知道, 常量指標指向**不可以改變, 這一點和引用的三大特性之一:引用所指向的物件不可以改變, 是一致的。 由此我們可以解開乙個迷惑,那就是為什麼c++ **中很少使用常量指標,而經常使用指向常量的指標。原因就是使用引用比使用乙個常量指標更簡單更直觀。
使用引用比使用乙個常量指標更簡單更直觀,應該盡量避免使用常量指標,而應該使用引用替代。好了最後讓我們看一看如何用引用取代指向常量的常量指標
const t* const cpct = pt;
const t& rct = *pt;
常量指標和指向常量的指標
首先指出乙個錯誤,壓根就不應該有指標常量這個說法。經常聽到有關常量指標和指標常量的討論,也經常見到有關兩者區別的文章,然而,有些文章卻誤導了讀者,他們的結論根本就是錯的。例如關於指標常量和常量指標的討論,結果完全顛倒了 而其他一些文章呢,充其量只是火上加油,讓本來就很複雜的事情變得更加難於理解,例如...
常量指標和指向常量的指標
1 常量指標 指標本身的位址值不可修改,這個值是定義指標的時候確定的,以後不可再改變。定義 int const i new int i是常量,執行i 會出錯 const修飾的是i,所以i不能變。2 指向常量的指標 該指標指向的變數是不可修改的。定義 const int i new int 100 或...
指向常量的指標和常量指標
指向常量的指標和常量指標 雨竹清風 指向常量的指標 是指該指標指向的是一常量,不能改變的是所指物件的值。要想存放常量物件的位址,只能使用指向常量的指標。常量指標 指的是該指標是一常量,即指標的位址不能改變。1 指向常量的指標 const int p 2.1 const double pi 3.14 ...