在學習函式多載的時候, 注意到了函式多載與 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
頂層 const
在 C++ 標準中有提及, 但是底層 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
所限定的物件了
自創文章, 原著 : Jonny. 如若閣下需要轉發, 在已經授權的情況下請註明本文出處 :