在學習函式多載的時候, 注意到了函式多載與 const 限定詞的關係, 細節將在《C++ 學習筆記》中介紹. 因為在看書的時候, 涉及到了 頂層 const 與 底層 const 的概念, 所以重新對 const 進行了學習

const 限定詞說到底, 實際上是對某個變數 (包括指標、參考、變數) 進行限定, 使其無法通過 const 宣告後的變數進行修改

《C++ 學習筆記》中, 對於 const 的介紹並不多, 不足以學習 const 與函式多載, 於是在此補充

頂層 const 和 底層 const 在《C++ 學習筆記》中已經有介紹, 這裡不再進行教學

我們可以看到下面兩個例子

#include <iostream>


using namespace std;

int main(int argc, char *argv[]) {

	int **ptr = (int **)new int *[10];

	for(size_t i = 0; i < 9; i++) {

		ptr[i] = new int;

	}

	const int **cstptr = const_cast<const int **>(ptr);

	const int **const cstptr2 = const_cast<const int **const>(cstptr);

	const int *const *cstptr3 = const_cast<const int *const *>(cstptr2);

}

如果通過 頂層 const 和 底層 const 的定義去了解最後兩行陳述式

首先看到第一個陳述式

const int **const cstptr2 = const_cast<const int **>(cstptr);

cstptr2 是一個指標, 它被前面的 const 所限定, 所以上句中的第二個 const 實際上屬於頂層 const; **cstptr2 是一個指標指向的物件, 它同樣也被前面的 const 所限定, 所以第一個 const 屬於底層 const

再來看第二句

const int *const *cstptr3 = const_cast<const int *const *>(cstptr2);

*cstptr3 是一個指標指向的物件, 被前面的 const 所限定, 所以第二個 const 屬於底層 const; **cstptr3 同樣是一個指標指向的物件, 被前面的 const 所限定, 所以第一個 const 同樣屬於底層 const

此時, 對於初學的而言, 可能會無法清楚到底什麼是頂層 const, 什麼是底層 const

頂層 constC++ 標準中有提及, 但是底層 const 並未被提及, 它是《C++ Primer》中被撰寫者所創建. 作者原意想讓我們更好地理解 const, 但是實際上我們對此的理解更加混亂

其實並無需要去理解什麼是 頂層 const 與 底層 const, 這樣去理解可能更清楚 :

拿到一個宣告陳述式, 首先將類似於

const T a 改寫為 T const a

從右往左閱讀陳述式, 當陳述式中出現指標, 並且 const 在 解參考運算元的前面的時候, 它所限定的是一個指標指向的物件. 當 const 出現在解參考運算元 * 的後面時, 它所限定的是一個指標. 用一個實例說明 :

const T *const *const ***const *const ptr

首先改寫為

T const *const *const ***const *const ptr

從左往右分別是第一個 const、第二個 const 以此. 首先從右往左

右邊第一個 const, 也就是第五個 const, 它是限定 ptr 的. 也就是說, ptr 被限定為常數; 右邊第二個, 也就是低四個 const, 它限定 *ptr, 也就是 *ptr 為常數; 右邊第三個, 它限定 ****ptr, 也就是 ****ptr 為常數; 右邊低四個 const, 也就是第二個 const, 它限定 *****ptr, 也就是說 *****ptr 為常數; 右邊第五個, 也就是第一個 const, 限定了 ******ptr

通過上述限定, 除了 **ptr 和 ***ptr 不是常數之外, 其它都被 const 限定為常數

正是因為指標的原因, 才使得 C++ 的 const 如此複雜

最終, 我們做一個總結 :

  • 當一個 const 後面沒有解參考運算元 * 的時候, 它限定了一個指標
  • 當一個 const 後面存在解參考運算元 * 的時候, 它限定了指標指向的物件

const 是支援巢狀的, 拿著這個總結, 從右向左閱讀陳述式, 就可以搞清楚每個 const 所限定的物件了