const 是 constant 的縮寫,本意是不變的,不易改變的意思。在 C++ 中是用來修飾內(nèi)置類型變量,自定義對(duì)象,成員函數(shù),返回值,函數(shù)參數(shù)。
C++ const 允許指定一個(gè)語義約束,編譯器會(huì)強(qiáng)制實(shí)施這個(gè)約束,允許程序員告訴編譯器某值是保持不變的。如果在編程中確實(shí)有某個(gè)值保持不變,就應(yīng)該明確使用const,這樣可以獲得編譯器的幫助。
一、const修飾普通類型的變量
const int a = 7; int b = a; // 正確 a = 8; // 錯(cuò)誤,不能改變
a 被定義為一個(gè)常量,并且可以將 a 賦值給 b,但是不能給 a 再次賦值。對(duì)一個(gè)常量賦值是違法的事情,因?yàn)?a 被編譯器認(rèn)為是一個(gè)常量,其值不允許修改。
接著看如下的操作:
實(shí)例
對(duì)于 const 變量 a,我們?nèi)∽兞康牡刂凡⑥D(zhuǎn)換賦值給 指向 int 的指針,然后利用 *p = 8; 重新對(duì)變量 a 地址內(nèi)的值賦值,然后輸出查看 a 的值。
從下面的調(diào)試窗口看到 a 的值被改變?yōu)?8,但是輸出的結(jié)果仍然是 7。
從結(jié)果中我們可以看到,編譯器然后認(rèn)為 a 的值為一開始定義的 7,所以對(duì) const a 的操作就會(huì)產(chǎn)生上面的情況。所以千萬不要輕易對(duì) const 變量設(shè)法賦值,這會(huì)產(chǎn)生意想不到的行為。
如果不想讓編譯器察覺到上面到對(duì) const 的操作,我們可以在 const 前面加上 volatile 關(guān)鍵字。
Volatile 關(guān)鍵字跟 const 對(duì)應(yīng)相反,是易變的,容易改變的意思。所以不會(huì)被編譯器優(yōu)化,編譯器也就不會(huì)改變對(duì) a 變量的操作。
實(shí)例
輸出結(jié)果如我們期望的是 8。
二、const 修飾指針變量。
const 修飾指針變量有以下三種情況。
- A: const 修飾指針指向的內(nèi)容,則內(nèi)容為不可變量。
- B: const 修飾指針,則指針為不可變量。
- C: const 修飾指針和指針指向的內(nèi)容,則指針和指針指向的內(nèi)容都為不可變量。
對(duì)于 A:
const int *p = 8;
則指針指向的內(nèi)容 8 不可改變。簡(jiǎn)稱左定值,因?yàn)?const 位于 * 號(hào)的左邊。
對(duì)于 B:
int a = 8; int* const p = &a; *p = 9; // 正確 int b = 7; p = &b; // 錯(cuò)誤
對(duì)于 const 指針 p 其指向的內(nèi)存地址不能夠被改變,但其內(nèi)容可以改變。簡(jiǎn)稱,右定向。因?yàn)?const 位于 * 號(hào)的右邊。
對(duì)于 C: 則是 A 和 B的合并
int a = 8; const int * const p = &a;
這時(shí),const p 的指向的內(nèi)容和指向的內(nèi)存地址都已固定,不可改變。
對(duì)于 A,B,C 三種情況,根據(jù) const 位于 * 號(hào)的位置不同,我總結(jié)三句話便于記憶的話:“左定值,右定向,const修飾不變量”。
三、const參數(shù)傳遞和函數(shù)返回值。
對(duì)于 const 修飾函數(shù)參數(shù)可以分為三種情況。
A:值傳遞的 const 修飾傳遞,一般這種情況不需要 const 修飾,因?yàn)楹瘮?shù)會(huì)自動(dòng)產(chǎn)生臨時(shí)變量復(fù)制實(shí)參值。
實(shí)例
B:當(dāng) const 參數(shù)為指針時(shí),可以防止指針被意外篡改。
實(shí)例
C:自定義類型的參數(shù)傳遞,需要臨時(shí)對(duì)象復(fù)制參數(shù),對(duì)于臨時(shí)對(duì)象的構(gòu)造,需要調(diào)用構(gòu)造函數(shù),比較浪費(fèi)時(shí)間,因此我們采取 const 外加引用傳遞的方法。
并且對(duì)于一般的 int、double 等內(nèi)置類型,我們不采用引用的傳遞方式。
實(shí)例
結(jié)果輸出 8。
對(duì)于 const 修飾函數(shù)的返回值。
Const 修飾返回值分三種情況。
A:const 修飾內(nèi)置類型的返回值,修飾與不修飾返回值作用一樣。
實(shí)例
B: const 修飾自定義類型的作為返回值,此時(shí)返回的值不能作為左值使用,既不能被賦值,也不能被修改。
C: const 修飾返回的指針或者引用,是否返回一個(gè)指向 const 的指針,取決于我們想讓用戶干什么。
四、const修飾類成員函數(shù)
const 修飾類成員函數(shù),其目的是防止成員函數(shù)修改被調(diào)用對(duì)象的值,如果我們不想修改一個(gè)調(diào)用對(duì)象的值,所有的成員函數(shù)都應(yīng)當(dāng)聲明為 const 成員函數(shù)。
注意:const 關(guān)鍵字不能與 static 關(guān)鍵字同時(shí)使用,因?yàn)?static 關(guān)鍵字修飾靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)不含有 this 指針,即不能實(shí)例化,const 成員函數(shù)必須具體到某一實(shí)例。
下面的 get_cm()const; 函數(shù)用到了 const 成員函數(shù):
實(shí)例
如果 get_cm() 去掉 const 修飾,則 Cmf 傳遞的 const _tt 即使沒有改變對(duì)象的值,編譯器也認(rèn)為函數(shù)會(huì)改變對(duì)象的值,所以我們盡量按照要求將所有的不需要改變對(duì)象內(nèi)容的函數(shù)都作為 const 成員函數(shù)。
如果有個(gè)成員函數(shù)想修改對(duì)象中的某一個(gè)成員怎么辦?這時(shí)我們可以使用 mutable 關(guān)鍵字修飾這個(gè)成員,mutable 的意思也是易變的,容易改變的意思,被 mutable 關(guān)鍵字修飾的成員可以處于不斷變化中,如下面的例子。
實(shí)例
這里我們?cè)?Kf()const 中通過 ++_ct; 修改 _ct 的值,但是通過 ++_cm 修改 _cm 則會(huì)報(bào)錯(cuò)。因?yàn)?++_cm 沒有用 mutable 修飾。
原文地址:https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html