C++中const關(guān)鍵字的使用方法

??? 之前一直在學(xué)習(xí)C/C++尚骄,關(guān)于const的使用,這里出現(xiàn)一點(diǎn)侵续,那里出現(xiàn)一點(diǎn)倔丈。知識(shí)用時(shí)方恨少,這一段時(shí)間正好各種筆試題询兴,其中關(guān)于const的用法也是層出不窮乃沙,所以疲于在書(shū)本上各種翻起趾,這里匯總一下诗舰,加深自己的印象的同時(shí),也方便以后查閱和學(xué)習(xí)训裆。菜鳥(niǎo)一個(gè)眶根,若有錯(cuò)誤,望指正边琉!

  1. const關(guān)鍵字

常類(lèi)型是指使用類(lèi)型修飾符const說(shuō)明的類(lèi)型属百,常類(lèi)型的變量或?qū)ο蟮闹凳遣荒鼙桓碌摹2还艹霈F(xiàn)在任何上下文都是為這個(gè)目的而服務(wù)的变姨。????

  1. const使用方法

  • 定義const對(duì)象

    const修飾符可以把對(duì)象轉(zhuǎn)變成常數(shù)對(duì)象族扰,意思就是說(shuō)利用const進(jìn)行修飾的變量的值在程序的任意位置將不能再被修改,就如同常數(shù)一樣使用!任何修改該變量的嘗試都會(huì)導(dǎo)致編譯錯(cuò)誤:

??? 注意:因?yàn)槌A吭诙ㄒ院缶筒荒鼙恍薷挠婧牵远x時(shí)必須初始化:

??????? 對(duì)于類(lèi)中的const成員變量必須通過(guò)初始化列表進(jìn)行初始化怒竿,如下所示:


  • const對(duì)象默認(rèn)為文件的局部變量

在全局作用域里定義非const變量時(shí),它在整個(gè)程序中都可以訪問(wèn)扩氢,我們可以把一個(gè)非const變量定義在一個(gè)文件中,假設(shè)已經(jīng)做了合適的聲明,就可以在另外的文件中使用這個(gè)變量:

與其他變量不同晕翠,除非特別說(shuō)明盖文,在全局作用域聲明的const變量是定義該對(duì)象的文件的局部變量。此變量只存在于那個(gè)文件中双饥,不能被其他文件訪問(wèn)媒抠。通過(guò)指定const變量為extern,就可以在整個(gè)程序中訪問(wèn)const對(duì)象咏花。

注意:非const變量默認(rèn)為extern领舰。要使const變量能夠在其他文件中訪問(wèn),必須在文件中顯式地指定它為extern迟螺。

  • const 引用

    const引用是指向const對(duì)象的引用


可以讀取但不能修改refVal冲秽,因此,任何對(duì)refVal的賦值都是不合法的矩父。這個(gè)限制有其意義:不能直接對(duì)ival賦值锉桑,因此不能通過(guò)使用refVal來(lái)修改ival。同理窍株,用ival初始化ref2也是不合法的:ref2是普通的非const引用民轴,因此可以用來(lái)修改ref2指向的對(duì)象的值。通過(guò)ref2對(duì)ival賦值會(huì)導(dǎo)致修改const對(duì)象的值球订,為防止這樣的修改后裸,需要規(guī)定將普通的引用綁定到const對(duì)象是不合法的。 const 引用可以初始化為不同類(lèi)型的對(duì)象或者初始化為右值冒滩。如字面值常量:

同樣的初始化對(duì)于非const引用卻是不合法的微驶,而且會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤。其原因非常微妙开睡,值得解釋一下因苹。觀察將引用綁定到不同的類(lèi)型時(shí)所發(fā)生的事情,最容易理解上述行為篇恒。對(duì)于下一段代碼:

編譯器會(huì)將這些代碼轉(zhuǎn)換為一下形式:

我們發(fā)現(xiàn)編譯器會(huì)創(chuàng)建一個(gè)int型的暫時(shí)變量存儲(chǔ)dval扶檐,然后將ri綁定到temp上。

注意:引用在內(nèi)部存放的是一個(gè)對(duì)象的地址胁艰,它是該對(duì)象的別名款筑。對(duì)于不可尋址的值智蝠,如文字常量,以及不同類(lèi)型的對(duì)象奈梳,編譯器為了實(shí)現(xiàn)引用寻咒,必須生成一個(gè)臨時(shí)對(duì)象,引用實(shí)際上指向該對(duì)象颈嚼,但用戶(hù)不能訪問(wèn)它毛秘。

如果ri不是const,那么可以給ri賦一新值阻课。這樣做不會(huì)修改dval的叫挟,而是修改了temp。期望對(duì)ri賦值會(huì)修改dval的程序員會(huì)發(fā)現(xiàn)dval沒(méi)有被修改限煞。僅允許const引用綁定到需要臨時(shí)使用的值完全避免了這個(gè)問(wèn)題抹恳,直接告訴程序員不能修改,因?yàn)閏onst引用是只讀的哈~(其實(shí)就是避免程序員心理預(yù)期產(chǎn)生反差署驻。奋献。。)

注意:非const引用只能綁定到與該引用相同類(lèi)型的對(duì)象旺上。 const引用則可以綁定到不同但相關(guān)的類(lèi)型的對(duì)象或綁定到右值瓶蚂。

  • const對(duì)象的動(dòng)態(tài)數(shù)組

如果我們?cè)谧杂纱鎯?chǔ)區(qū)中創(chuàng)建的數(shù)組存儲(chǔ)了內(nèi)置類(lèi)型的const對(duì)象,則必須為這個(gè)數(shù)組提供初始化: 因?yàn)閿?shù)組元素都是const對(duì)象宣吱,無(wú)法賦值窃这。實(shí)現(xiàn)這個(gè)要求的唯一方法是對(duì)數(shù)組做值初始化。

C++允許定義類(lèi)類(lèi)型的const數(shù)組征候,但該類(lèi)類(lèi)型必須提供默認(rèn)構(gòu)造函數(shù):

  • 指針和const限定符的關(guān)系(重點(diǎn):脊ァ!0贪印U捉狻!E苋唷锅睛!非常容易搞混)

    const限定符和指針結(jié)合起來(lái)常見(jiàn)的情況有以下幾種。

  1. 指向常量的指針(指向const對(duì)象的指針)


? C++為了保證不允許使用指針改變所指的const值這個(gè)特性畔裕,強(qiáng)制要求這個(gè)指針也必須具備const特性:

這里cptr是一個(gè)指向double類(lèi)型const對(duì)象的指針衣撬,const先頂了cptr指向的對(duì)象的類(lèi)型乖订,而并非cptr本身扮饶,所以cptr本身并不是const。所以定義的時(shí)候并不需要對(duì)它進(jìn)行初始乍构,如果需要的話甜无,允許給cptr重新賦值扛点,讓其指向另一個(gè)const對(duì)象。但不能通過(guò)cptr修改其所指對(duì)象的值岂丘。

而我們將一個(gè)const對(duì)象的地址賦給一個(gè)普通的非const指針也會(huì)導(dǎo)致編譯錯(cuò)誤陵究。

不能使用void*指針保存const對(duì)象的地址,必須使用const void*類(lèi)型的指針保存const對(duì)象的地址奥帘。

下面令人頭暈的一個(gè)問(wèn)題來(lái)了----à 允許把非const對(duì)象的地址賦給指向const對(duì)象的指針铜邮,例如:

但是我們不能通過(guò)cptr指針來(lái)修改dval的值!U!松蒜!即使它指向的是非const對(duì)象。

然后已旧,我們一定要知道秸苗,不能使用指向const對(duì)象的指針修改基礎(chǔ)對(duì)象,然而如果該指針指向了非const對(duì)象运褪,可用其他方式修改其所指的對(duì)象惊楼,所以事實(shí)上,可以修改const指針?biāo)赶虻闹档慕斩铮遣荒芡ㄟ^(guò)const對(duì)象指針來(lái)進(jìn)行而已檀咙!如下所示:

通過(guò)以上,我們知道指向const對(duì)象的指針 確切的講: 自以為指向const的指針璃诀!

  1. 常指針(const指針)


C++中還提供了const指針——本身的值不能被修改攀芯。


??????? 我們可以從右往左把上述定義語(yǔ)句讀作"指向int型對(duì)象的const指針"。與其他const量一樣文虏,const指針的值不能被修改侣诺,這意味著不能使curErr指向其他對(duì)象。Const指針也必須在定義的時(shí)候初始化氧秘。

??????? 指針本身是const的試試并沒(méi)有說(shuō)明是否能用改真真修改其所指向的對(duì)象的值年鸳。指針對(duì)象的值能否修改完全取決于該對(duì)象的類(lèi)型。

  1. 指向常量的常指針(指向const對(duì)象的const指針)


如下可以這樣定義:



這樣pi_ptr首先是一個(gè)const指針丸相,然后其指向一個(gè)const對(duì)象~~~

  • 函數(shù)和const限定符的關(guān)系(另一難點(diǎn)Iθ贰!灭忠!理解)
  1. 類(lèi)中的const成員函數(shù)(常量成員函數(shù))


在一個(gè)類(lèi)中膳算,任何不會(huì)修改數(shù)據(jù)成員的函數(shù)都應(yīng)該聲明為const類(lèi)型。如果在編寫(xiě)const成員函數(shù)時(shí)弛作,不慎修改了數(shù)據(jù)成員涕蜂,或者調(diào)用了其它非const成員函數(shù),編譯器將指出錯(cuò)誤映琳,這無(wú)疑會(huì)提高程序的健壯性机隙。使用const關(guān)鍵字進(jìn)行說(shuō)明的成員函數(shù)蜘拉,稱(chēng)為常成員函數(shù)。只有常成員函數(shù)才有資格操作常量或常對(duì)象有鹿,沒(méi)有使用const關(guān)鍵字說(shuō)明的成員函數(shù)不能用來(lái)操作常對(duì)象旭旭。常成員函數(shù)說(shuō)明格式如下:

  <類(lèi)型說(shuō)明符> <函數(shù)名> (<參數(shù)表>) const;


其中葱跋,const是加在函數(shù)說(shuō)明后面的類(lèi)型修飾符持寄,它是函數(shù)類(lèi)型的一個(gè)組成部分,因此娱俺,在函數(shù)實(shí)現(xiàn)部分也要帶const關(guān)鍵字际看。下面舉一例子說(shuō)明常成員函數(shù)的特征。

    1. 函數(shù)重載


既然const是定義為const函數(shù)的組成部分矢否,那么就可以通過(guò)添加const實(shí)現(xiàn)函數(shù)重載咯仲闽。

其中print成員函數(shù)就實(shí)現(xiàn)了兩個(gè)版本~~~ 重載哦,輸出結(jié)果為 5,52僵朗。 const對(duì)象默認(rèn)調(diào)用const成員函數(shù)赖欣。

  1. const 修飾函數(shù)返回值

const修飾函數(shù)返回值其實(shí)用的并不是很多,它的含義和const修飾普通變量以及指針的含義基本相同验庙。如下所示:

一般情況下顶吮,函數(shù)的返回值為某個(gè)對(duì)象時(shí),如果將其聲明為const時(shí)粪薛,多用于操作符的重載悴了。通常,不建議用const修飾函數(shù)的返回值類(lèi)型為某個(gè)對(duì)象或?qū)δ硞€(gè)對(duì)象引用的情況违寿。原因如下:如果返回值為某個(gè)對(duì)象為const(const A test = A 實(shí)例)或某個(gè)對(duì)象的引用為const(const A& test = A實(shí)例) 湃交,則返回值具有const屬性,則返回實(shí)例只能訪問(wèn)類(lèi)A中的公有(保護(hù))數(shù)據(jù)成員和const成員函數(shù)藤巢,并且不允許對(duì)其進(jìn)行賦值操作搞莺,這在一般情況下很少用到。??

  1. const修飾函數(shù)參數(shù)






?????? 這樣的一個(gè)const引用傳遞和最普通的函數(shù)按值傳遞的效果是一模一樣的,他禁止對(duì)引用的對(duì)象的一切修改,唯一不同的是按值傳遞會(huì)先建立一個(gè)類(lèi)對(duì)象的副本, 然后傳遞過(guò)去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個(gè)臨時(shí)對(duì)象,因?yàn)榕R時(shí)對(duì)象都是const屬性, 且是不可見(jiàn)的,他短時(shí)間存在一個(gè)局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個(gè)家伙.

  1. const定義的常量在超出其作用域之后其空間會(huì)被釋放温圆,而static定義的靜態(tài)常量在函數(shù)執(zhí)行后不會(huì)釋放其存儲(chǔ)空間。
  2. static表示的是靜態(tài)的孩革。類(lèi)的靜態(tài)成員函數(shù)岁歉、靜態(tài)成員變量是和類(lèi)相關(guān)的,而不是和類(lèi)的具體對(duì)象相關(guān)的嫉戚。即使沒(méi)有具體對(duì)象刨裆,也能調(diào)用類(lèi)的靜態(tài)成員函數(shù)和成員變量澈圈。一般類(lèi)的靜態(tài)函數(shù)幾乎就是一個(gè)全局函數(shù)彬檀,只不過(guò)它的作用域限于包含它的文件中帆啃。
  3. 在C++中,static靜態(tài)成員變量不能在類(lèi)的內(nèi)部初始化窍帝。在類(lèi)的內(nèi)部只是聲明努潘,定義必須在類(lèi)定義體的外部,通常在類(lèi)的實(shí)現(xiàn)文件中初始化坤学,如:double Account::Rate=2.25; static關(guān)鍵字只能用于類(lèi)定義體內(nèi)部的聲明中疯坤,定義時(shí)不能標(biāo)示為static
  4. 在C++中,const成員變量也不能在類(lèi)定義處初始化深浮,只能通過(guò)構(gòu)造函數(shù)初始化列表進(jìn)行压怠,并且必須有構(gòu)造函數(shù)。
  5. const數(shù)據(jù)成員,只在某個(gè)對(duì)象生存期內(nèi)是常量飞苇,而對(duì)于整個(gè)類(lèi)而言卻是可變的菌瘫。因?yàn)轭?lèi)可以創(chuàng)建多個(gè)對(duì)象,不同的對(duì)象其const數(shù)據(jù)成員的值可以不同布卡。所以不能在類(lèi)的聲明中初始化const數(shù)據(jù)成員雨让,因?yàn)轭?lèi)的對(duì)象沒(méi)被創(chuàng)建時(shí),編譯器不知道const數(shù)據(jù)成員的值是什么忿等。
  6. const數(shù)據(jù)成員的初始化只能在類(lèi)的構(gòu)造函數(shù)的初始化列表中進(jìn)行栖忠。要想建立在整個(gè)類(lèi)中都恒定的常量,應(yīng)該用類(lèi)中的枚舉常量來(lái)實(shí)現(xiàn)贸街,或者static const庵寞。
  7. const成員函數(shù)主要目的是防止成員函數(shù)修改對(duì)象的內(nèi)容。即const成員函數(shù)不能修改成員變量的值薛匪,但可以訪問(wèn)成員變量皇帮。當(dāng)方法成員函數(shù)時(shí),該函數(shù)只能是const成員函數(shù)蛋辈。

其中關(guān)于static属拾、const、static cosnt冷溶、const static成員的初始化問(wèn)題:


???? 在一個(gè)類(lèi)里建立一個(gè)const時(shí)渐白,不能給他初值



????? 類(lèi)中的static變量是屬于類(lèi)的,不屬于某個(gè)對(duì)象逞频,它在整個(gè)程序的運(yùn)行過(guò)程中只有一個(gè)副本纯衍,因此不能在定義對(duì)象時(shí) 對(duì)變量進(jìn)行初始化,就是不能用構(gòu)造函數(shù)進(jìn)行初始化苗胀,其正確的初始化方法是:


數(shù)據(jù)類(lèi)型 類(lèi)名::靜態(tài)數(shù)據(jù)成員名=值


?????? 最后通過(guò)一個(gè)完整的例子展示以上結(jié)果:



如果函數(shù)需要傳入一個(gè)指針,面試官可能會(huì)問(wèn)是否需要為該指針加上const歌亲,把const加在指針不同的位置有什么區(qū)別菇用;如果寫(xiě)的函數(shù)需要傳入的參數(shù)是一個(gè)復(fù)雜類(lèi)型的實(shí)例,面試官可能會(huì)問(wèn)傳入值參數(shù)或者引用參數(shù)有什么區(qū)別陷揪,什么時(shí)候需要為傳入的引用參數(shù)加上const惋鸥。 const是用來(lái)聲明一個(gè)常量的,當(dāng)你不想讓一個(gè)值被改變時(shí)就用const悍缠,const int max和int const max 是沒(méi)有區(qū)別的卦绣,都可以。不涉及到指針const很好理解飞蚓。一旦涉及到指針滤港,則比較容易出問(wèn)題。



如果const位于星號(hào)的左側(cè)趴拧,則const就是用來(lái)修飾指針?biāo)赶虻淖兞拷ρ粗羔樦赶虻膶?duì)象為常量;如果const位于星號(hào)的右側(cè)八堡,const就是修飾指針本身樟凄,即指針本身是常量。


因此兄渺,[1]和[2]的情況相同缝龄,都是指針?biāo)赶虻膬?nèi)容為常量(const放在變量聲明符的位置無(wú)關(guān)),這種情況下不允許對(duì)內(nèi)容進(jìn)行更改操作挂谍,如不能*a = 3 叔壤;[3]為指針本身是常量,而指針?biāo)赶虻膬?nèi)容不是常量口叙,這種情況下不能對(duì)指針本身進(jìn)行更改操作炼绘,如a++是錯(cuò)誤的;[4]為指針本身和指向的內(nèi)容均為常量妄田。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俺亮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疟呐,更是在濱河造成了極大的恐慌脚曾,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件启具,死亡現(xiàn)場(chǎng)離奇詭異本讥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)拷沸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)色查,“玉大人,你說(shuō)我怎么就攤上這事撞芍⊙砹耍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵勤庐,是天一觀的道長(zhǎng)示惊。 經(jīng)常有香客問(wèn)我好港,道長(zhǎng)愉镰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任钧汹,我火速辦了婚禮丈探,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拔莱。我一直安慰自己碗降,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布塘秦。 她就那樣靜靜地躺著讼渊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尊剔。 梳的紋絲不亂的頭發(fā)上爪幻,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音须误,去河邊找鬼挨稿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛京痢,可吹牛的內(nèi)容都是我干的奶甘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祭椰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼臭家!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起方淤,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钉赁,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后臣淤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體橄霉,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姓蜂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片按厘。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钱慢,靈堂內(nèi)的尸體忽然破棺而出逮京,到底是詐尸還是另有隱情,我是刑警寧澤束莫,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布懒棉,位于F島的核電站,受9級(jí)特大地震影響览绿,放射性物質(zhì)發(fā)生泄漏策严。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一饿敲、第九天 我趴在偏房一處隱蔽的房頂上張望妻导。 院中可真熱鬧,春花似錦怀各、人聲如沸倔韭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寿酌。三九已至,卻和暖如春硕蛹,著一層夾襖步出監(jiān)牢的瞬間醇疼,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工妓美, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僵腺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓壶栋,卻偏偏與公主長(zhǎng)得像辰如,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贵试,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容