C++ const 總結
const 是 constant 的縮寫,本意是不變的,不易改變的意思。在 C++ 中是用來修飾內建型別變數,自定義物件,成員函式,返回值,函式引數。 |
C++ const 允許指定一個語義約束,編譯器會強制實施這個約束,允許程式設計師告訴編譯器某值是保持不變的。如果在程式設計中確實有某個值保持不變,就應該明確使用const,這樣可以獲得編譯器的幫助。
const int a = 7; int b = a; // 正確 a = 8; // 錯誤,不能改變
a 被定義為一個常量,並且可以將 a 賦值給 b,但是不能給 a 再次賦值。對一個常量賦值是違法的事情,因為 a 被編譯器認為是一個常量,其值不允許修改。
接著看如下的操作:
例項
#includeusing namespace std; int main(void) { const int a = 7; int *p = (int*)&a; *p = 8; cout<<1a; system("pause");="" return="" 0;="" }
對於 const 變數 a,我們取變數的地址並轉換賦值給 指向 int 的指標,然後利用 *p = 8; 重新對變數 a 地址內的值賦值,然後輸出檢視 a 的值。
從下面的除錯視窗看到 a 的值被改變為 8,但是輸出的結果仍然是 7。
從結果中我們可以看到,編譯器然後認為 a 的值為一開始定義的 7,所以對 const a 的操作就會產生上面的情況。所以千萬不要輕易對 const 變數設法賦值,這會產生意想不到的行為。
如果不想讓編譯器察覺到上面到對 const 的操作,我們可以在 const 前面加上 volatile 關鍵字。
Volatile 關鍵字跟 const 對應相反,是易變的,容易改變的意思。所以不會被編譯器最佳化,編譯器也就不會改變對 a 變數的操作。
例項
#includeusing namespace std; int main(void) { volatile const int a = 7; int *p = (int*)&a; *p = 8; cout<<1a; system("pause");="" return="" 0;="" }
輸出結果如我們期望的是 8。
const 修飾指標變數有以下三種情況。
- A: const 修飾指標指向的內容,則內容為不可變數。
- B: const 修飾指標,則指標為不可變數。
- C: const 修飾指標和指標指向的內容,則指標和指標指向的內容都為不可變數。
對於 A:
const int *p = 8;
則指標指向的內容 8 不可改變。簡稱左定值,因為 const 位於 * 號的左邊。
對於 B:
int a = 8; int* const p = &a; *p = 9; // 正確 int b = 7; p = &b; // 錯誤
對於 const 指標 p 其指向的記憶體地址不能夠被改變,但其內容可以改變。簡稱,右定向。因為 const 位於 * 號的右邊。
對於 C: 則是 A 和 B的合併
int a = 8; const int * const p = &a;
這時,const p 的指向的內容和指向的記憶體地址都已固定,不可改變。
對於 A,B,C 三種情況,根據 const 位於 * 號的位置不同,我總結三句話便於記憶的話:"左定值,右定向,const修飾不變數"。
對於 const 修飾函式引數可以分為三種情況。
A:值傳遞的 const 修飾傳遞,一般這種情況不需要 const 修飾,因為函式會自動產生臨時變數複製實參值。
例項
#includeusing namespace std; void Cpf(const int a) { cout<<1a; ++a;="" 是錯誤的,a="" 不能被改變="" }="" int="" main(void)="" {="" cpf(8);="" system("pause");="" return="" 0;="" }
B:當 const 引數為指標時,可以防止指標被意外篡改。
例項
#includeusing namespace std; void Cpf(int *const a) { cout<<*a<<" "; *a = 9; } int main(void) { int a = 8; Cpf(&a); cout<<1a; a="" 為="" 9="" system("pause");="" return="" 0;="" }
C:自定義型別的引數傳遞,需要臨時物件複製引數,對於臨時物件的構造,需要呼叫建構函式,比較浪費時間,因此我們採取 const 外加引用傳遞的方法。
並且對於一般的 int、double 等內建型別,我們不採用引用的傳遞方式。
例項
#includeusing namespace std; class Test { public: Test(){} Test(int _m):_cm(_m){} int get_cm()const { return _cm; } private: int _cm; }; void Cmf(const Test& _tt) { cout<<_tt.get_cm(); } int main(void) { Test t(8); Cmf(t); system("pause"); return 0; }
結果輸出 8。
對於 const 修飾函式的返回值。
Const 修飾返回值分三種情況。
A:const 修飾內建型別的返回值,修飾與不修飾返回值作用一樣。
例項
#includeusing namespace std; const int Cmf() { return 1; } int Cpf() { return 0; } int main(void) { int _m = Cmf(); int _n = Cpf(); cout<<_m<<" "<<_n; system("pause"); return 0; }
B: const 修飾自定義型別的作為返回值,此時返回的值不能作為左值使用,既不能被賦值,也不能被修改。
C: const 修飾返回的指標或者引用,是否返回一個指向 const 的指標,取決於我們想讓使用者幹什麼。
const 修飾類成員函式,其目的是防止成員函式修改被呼叫物件的值,如果我們不想修改一個呼叫物件的值,所有的成員函式都應當宣告為 const 成員函式。
注意:const 關鍵字不能與 static 關鍵字同時使用,因為 static 關鍵字修飾靜態成員函式,靜態成員函式不含有 this 指標,即不能例項化,const 成員函式必須具體到某一例項。
下面的 get_cm()const; 函式用到了 const 成員函式:
例項
#includeusing namespace std; class Test { public: Test(){} Test(int _m):_cm(_m){} int get_cm()const { return _cm; } private: int _cm; }; void Cmf(const Test& _tt) { cout<<_tt.get_cm(); } int main(void) { Test t(8); Cmf(t); system("pause"); return 0; }
如果 get_cm() 去掉 const 修飾,則 Cmf 傳遞的 const _tt 即使沒有改變物件的值,編譯器也認為函式會改變物件的值,所以我們儘量按照要求將所有的不需要改變物件內容的函式都作為 const 成員函式。
如果有個成員函式想修改物件中的某一個成員怎麼辦?這時我們可以使用 mutable 關鍵字修飾這個成員,mutable 的意思也是易變的,容易改變的意思,被 mutable 關鍵字修飾的成員可以處於不斷變化中,如下面的例子。
例項
#includeusing namespace std; class Test { public: Test(int _m,int _t):_cm(_m),_ct(_t){} void Kf()const { ++_cm; // 錯誤 ++_ct; // 正確 } private: int _cm; mutable int _ct; }; int main(void) { Test t(8,7); return 0; }
這裡我們在 Kf()const 中透過 ++_ct; 修改 _ct 的值,但是透過 ++_cm 修改 _cm 則會報錯。因為 ++_cm 沒有用 mutable 修飾。
原文地址:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2715843/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++中const用法總結C++
- C/C++——const用法完整總結C++
- 關於C++ const 的全面總結C++
- C++中const與指標、引用的總結C++指標
- Const 用法總結
- C++中const小結C++
- const特性總結(不斷更新)
- C++ const int * ; int * constC++
- C++ 頂層const底層constC++
- C++基礎 constC++
- C++:字串總結C++字串
- let & const —— ES6基礎總結(二)
- C++中const的用法C++
- C/C++中的constC++
- C++中const的妙用C++
- C++ const常量的理解C++
- C++ constexp vs constC++
- 【C++】 C++知識點總結C++
- C++除錯總結C++除錯
- c++學習總結C++
- 【C++泛讀總結】C++
- C++ STL容器總結C++
- C++基礎總結C++
- C++ 中的 const 物件與 const 成員函式C++物件函式
- c++方法後面加constC++
- C/C++ Const 小知識C++
- c/c++ const關鍵字C++
- c++ const 成員函式C++函式
- C++之const限定符C++
- C++primer1-7章知識點總結——頂層const與底層constC++
- C/C++指標總結C++指標
- C++設計模式 - 總結C++設計模式
- 面試總結(C++基礎)面試C++
- C++ 14 新特性總結C++
- 關於C/C++ const變數 const指標 以及C++ 引用變數的解析C++變數指標
- 關於es6 let var const 以及Symbol的總結Symbol
- C++中const的簡單用法C++
- C++中的 const 關鍵字C++