C++ const變量使用技巧總結(jié)
在C++編程語(yǔ)言中,還有很多比較高深的內(nèi)容值得我們?cè)趯W(xué)習(xí)和實(shí)踐中不斷的學(xué)習(xí)。在這篇文章中,我們將會(huì)為大家詳細(xì)介紹有關(guān)C++ const變量的相關(guān)內(nèi)容,希望能幫助大家輕松了解這方面知識(shí)。
一、對(duì)于基本聲明
- const int r=100;
標(biāo)準(zhǔn)C++ const變量聲明加初始化,因?yàn)槟J(rèn)內(nèi)部連接所以必須被初始化,其作用域?yàn)榇宋募幾g器經(jīng)過(guò)類型檢查后直接用100在編譯時(shí)替換。
- extend const int r=100;
將const改為外部連接,作用于擴(kuò)大至全局,編譯時(shí)會(huì)分配內(nèi)存,并且可以不進(jìn)行初始化,僅僅作為聲明,編譯器認(rèn)為在程序其他地方進(jìn)行了定義。
- const int r[ ]={1,2,3,4};
- struct S {int a,b;};
- const S s[ ]={(1,2),(3.4)};
以上兩種都是常量集合,編譯器會(huì)為其分配內(nèi)存,所以不能在編譯期間使用其中的值,例如:int temp[r[2]];這樣的編譯器會(huì)報(bào)告不能找到常量表達(dá)式
二、對(duì)于指針
- 1.const int *r=&x;
聲明r為一個(gè)指向常量的x的指針,r指向的對(duì)象不能被修改,但他可以指向任何地址的常量。
- int const *r=&x;
與用法1完全等價(jià),沒(méi)有任何區(qū)別。
- int * const r=&x;
聲明r為一個(gè)常量指針,他指向x,r這個(gè)指針的指向不能被修改,但他指向的地址的內(nèi)容可以修改。
- const int * const r=&x;
綜合1、3用法,r是一個(gè)指向常量的常量型指針。
三、對(duì)于類型檢查
可以把一個(gè)非const對(duì)象賦給一個(gè)指向const的指針,因?yàn)橛袝r(shí)候我們不想從這個(gè)指針來(lái)修改其對(duì)象的值;但是不可以把一個(gè)C++ const變量對(duì)象賦值給一個(gè)非 const指針,因?yàn)檫@樣可能會(huì)通過(guò)這個(gè)指針改變指向?qū)ο蟮闹担泊嬖谑惯@種操作通過(guò)的合法化寫法,使用類型強(qiáng)制轉(zhuǎn)換可以通過(guò)指針改變const對(duì)象:
- const int r=100;
- int * ptr = const_cast(&r);
//C++標(biāo)準(zhǔn),C語(yǔ)言使用:int * ptr =(int*)&r;
四、對(duì)于字符數(shù)組
如char * name = “china”; 這樣的語(yǔ)句,在編譯時(shí)是能夠通過(guò)的,但是”china”是常量字符數(shù)組,任何想修改他的操作也能通過(guò)編譯但會(huì)引起運(yùn)行時(shí)錯(cuò)誤,如果我們想修改字符數(shù)組的話就要使用char name[ ] = “china”; 這種形式。
五、對(duì)于函數(shù)
- void Fuction1 ( const int r );
此處為參數(shù)傳遞C++ const變量值,意義是變量初值不能被函數(shù)改變
- const int Fuction1 (int);
此處返回const值,意思指返回的原函數(shù)里的變量的初值不能被修改,但是函數(shù)按值返回的這個(gè)變量被制成副本,能不能被修改就沒(méi)有了意義,它可以被賦給任何的const或非const類型變量,完全不需要加上這個(gè)const關(guān)鍵字。但這只對(duì)于內(nèi)部類型而言(因?yàn)閮?nèi)部類型返回的肯定是一個(gè)值,而不會(huì)返回一個(gè)變量,不會(huì)作為左值使用),對(duì)于用戶自定義類型,返回值是常量是非常重要的,見(jiàn)下面條款。
- Class CX; //內(nèi)部有構(gòu)造函數(shù),聲明如CX(int r =0)
- CX Fuction1 () { return CX(); }
- const CX Fuction2 () { return CX(); }
如有上面的自定義類CX,和函數(shù)Fuction1()和Fuction2(),我們進(jìn)行如下操作時(shí):
- Fuction1() = CX(1); //沒(méi)有問(wèn)題,可以作為左值調(diào)用
- Fuction2() = CX(1); //編譯錯(cuò)誤,const返回值禁止作為左值調(diào)用。
因?yàn)樽笾蛋逊祷刂底鳛樽兞繒?huì)修改其返回值,const聲明禁止這種修改。
4.函數(shù)中指針的C++ const變量傳遞和返回:
- int F1 (const char * pstr);
作為傳遞的時(shí)候使用const修飾可以保證不會(huì)通過(guò)這個(gè)指針來(lái)修改傳遞參數(shù)的初值,這里在函數(shù)內(nèi)部任何修改*pstr的企圖都會(huì)引起編譯錯(cuò)誤。
- const char * F2 ();
意義是函數(shù)返回的指針指向的對(duì)象是一個(gè)const對(duì)象,它必須賦給一個(gè)同樣是指向const對(duì)象的指針。
- const char * const F3();
比上面多了一個(gè)const,這個(gè)const的意義只是在他被用作左值時(shí)有效,它表明了這個(gè)指針除了指向const對(duì)象外,它本身也不能被修改,所以就不能當(dāng)作左值來(lái)處理。
5.函數(shù)中引用的const傳遞:
- void F1 ( const X& px);
這樣的一個(gè)C++ const變量引用傳遞和最普通的函數(shù)按值傳遞的效果是一模一樣的,他禁止對(duì)引用的對(duì)象的一切修改,唯一不同的是按值傳遞會(huì)先建立一個(gè)類對(duì)象的副本,然后傳遞過(guò)去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效。
另外只有引用的const傳遞可以傳遞一個(gè)臨時(shí)對(duì)象,因?yàn)榕R時(shí)對(duì)象都是const屬性,且是不可見(jiàn)的,他短時(shí)間存在一個(gè)局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個(gè)家伙。
六、對(duì)于類
1.首先,對(duì)于C++ const變量的成員變量,只能在構(gòu)造函數(shù)里使用初始化成員列表來(lái)初始化,試圖在構(gòu)造函數(shù)體內(nèi)進(jìn)行初始化const成員變量會(huì)引起編譯錯(cuò)誤。初始化成員列表形如:
- X:: X ( int ir ): r(ir) {}
假設(shè)r是類X的C++ const變量
2.const 成員函數(shù)。提到這個(gè)概念首先要談到const對(duì)象,正象內(nèi)置類型能夠定義const對(duì)象一樣(const int r=10;),用戶自定義類型也可以定義const對(duì)象(const X px(10);),編譯器要保證這個(gè)對(duì)象在其生命周期內(nèi)不能夠被改變。如果你定義了這樣的一個(gè)const對(duì)象,那么對(duì)于這個(gè)對(duì)象的一切非const成員函數(shù)的調(diào)用,編譯器為了保證對(duì)象的const特性,都會(huì)禁止并在編譯期間報(bào)錯(cuò)。所以如果你想讓你的成員函數(shù)能夠在const對(duì)象上進(jìn)行操作的話,就要把這個(gè)函數(shù)聲明為const成員函數(shù)。假如f( )是類中的成員函數(shù)的話,它的聲明形如:
- int f( ) const;
C++ const變量放在函數(shù)的***,編譯器會(huì)對(duì)這個(gè)函數(shù)進(jìn)行檢查,在這個(gè)函數(shù)中的任何試圖改變成員變量和調(diào)用非const成員函數(shù)的操作都被視為非法#t#
注意:類的構(gòu)造和析構(gòu)函數(shù)都不能是const函數(shù)。
3. 建立了一個(gè)const成員函數(shù),但仍然想用這個(gè)函數(shù)改變對(duì)象內(nèi)部的數(shù)據(jù)。這樣的一個(gè)要求也會(huì)經(jīng)常遇到,尤其是在一個(gè)苛刻的面試考官那里。首先我們要弄清楚考官的要求,因?yàn)橛袃煞N方法可以實(shí)現(xiàn),如果這位考官要求不改變?cè)瓉?lái)類的任何東西,只讓你從當(dāng)前這個(gè)const成員函數(shù)入手,那么你只有使用前面提到的類型強(qiáng)制轉(zhuǎn)換方法。
實(shí)例如下:假如有一個(gè)叫做X的類,它有一個(gè)int成員變量r,我們需要通過(guò)一個(gè)C++ const變量成員函數(shù)f( )來(lái)對(duì)這個(gè)r進(jìn)行++r操作,代碼如下
- void X::f( ) const
- { (const_cast(this)) -> ++r; } //通過(guò)this指針進(jìn)行類型強(qiáng)制轉(zhuǎn)換實(shí)現(xiàn)
另外一種方法就是使用關(guān)鍵字:mutable。如果你的成員變量在定義時(shí)是這個(gè)樣子的:
- mutable int r ;
那么它就告訴編譯器這個(gè)成員變量可以通過(guò)C++ const變量成員函數(shù)改變。編譯器就不會(huì)再理會(huì)對(duì)他的檢查了。