c 中對const的總結

2021-04-13 06:59:09 字數 3211 閱讀 7046

c++中const總結

對於基本宣告

1. const int r=100; //標準const變數宣告加初始化,因為預設內部連線所以必須被初始化,其作用域為此檔案,編譯器經過型別檢查後直接用100在編譯時替換

2. extend const int r=100; //將const改為外部連線,作用於擴大至全域性,編譯時會分配記憶體,並且可以不進行初始化,僅僅作為宣告,編譯器認為在程式其他地方進行了定義

3. const int r[ ]=;

struct s ;

const s s[ ]=; //以上兩種都是常量集合,編譯器會為其分配記憶體,所以不能在編譯期間使用其中的值,例如:int temp[r[2]];這樣的編譯器會報告不能找到常量表示式

對於指標

1. const int *r=&x; //宣告r為乙個指向常量的x的指標,r指向的物件不能被修改,但他可以指向任何位址的常量

2. int const *r=&x; //與用法1完全等價,沒有任何區別

3. int * const r=&x; //宣告r為乙個常量指標,他指向x,r這個指標的指向不能被修改,但他指向的位址的內容可以修改

4. const int * const r=&x; //綜合1、3用法,r是乙個指向常量的常量型指標

對於型別檢查

可以把乙個非const物件賦給乙個指向const的指標,因為有時候我們不想從這個指標來修改其物件的值;但是不可以把乙個const物件賦值給乙個非const指標,因為這樣可能會通過這個指標改變指向物件的值,但也存在使這種操作通過的合法化寫法,使用型別強制轉換可以通過指標改變const物件:

const int r=100;

int * ptr = const_cast(&r); //c++標準,c語言使用:int * ptr =(int*)&r;

對於字元陣列

如char * name = 「china」; 這樣的語句,在編譯時是能夠通過的,但是」china」是常量字元陣列,任何想修改他的操作也能通過編譯但會引起執行時錯誤,如果我們想修改字元陣列的話就要使用char name[ ] = 「china」; 這種形式。

對於函式

1. void fuction1 ( const int r ); //此處為引數傳遞const值,意義是變數初值不能被函式改變

2. const int fuction1 (int); //此處返回const值,意思指返回的原函式裡的變數的初值不能被修改,但是函式按值返回的這個變數被製成副本,能不能被修改就沒有了意義,它可以被賦給任何的const或非const型別變數,完全不需要加上這個const關鍵字。但這只對於內部型別而言(因為內部型別返回的肯定是乙個值,而不會返回乙個變數,不會作為左值使用),對於使用者自定義型別,返回值是常量是非常重要的,見下面條款3。

3. class cx; //內部有建構函式,宣告如cx(int r =0)

cx fuction1 ()

const cx fuction2 ()

如有上面的自定義類cx,和函式fuction1()和fuction2(),我們進行如下操作時:

fuction1() = cx(1); //沒有問題,可以作為左值呼叫

fuction2() = cx(1); //編譯錯誤,const返回值禁止作為左值呼叫。因為左值把返回值作為變數會修改其返回值,const宣告禁止這種修改。

4. 函式中指標的const傳遞和返回:

int f1 (const char * pstr); //作為傳遞的時候使用const修飾可以保證不會通過這個指標來修改傳遞引數的初值,這裡在函式內部任何修改*pstr的企圖都會引起編譯錯誤。

const char * f2 (); //意義是函式返回的指標指向的物件是乙個const物件,它必須賦給乙個同樣是指向const物件的指標。

const char * const f3(); //比上面多了乙個const,這個const的意義只是在他被用作左值時有效,它表明了這個指標除了指向const物件外,它本身也不能被修改,所以就不能當作左值來處理。

5. 函式中引用的const傳遞:

void f1 ( const x& px); //這樣的乙個const引用傳遞和最普通的函式按值傳遞的效果是一模一樣的,他禁止對引用的物件的一切修改,唯一不同的是按值傳遞會先建立乙個類物件的副本,然後傳遞過去,而它直接傳遞位址,所以這種傳遞比按值傳遞更有效。

**另外只有引用的const傳遞可以傳遞乙個臨時物件 ,因為臨時物件都是const屬性,且是不可見的,他短時間存在乙個區域性域中,所以不能使用指標,只有引用的const傳遞能夠捕捉到這個傢伙。

對於類1. 首先,對於const的成員變數,只能在建構函式裡使用初始化成員列表來初始化,試圖在建構函式體內進行初始化const成員變數會引起編譯錯誤。初始化成員列表形如:

x:: x ( int ir ): r(ir) {} //假設r是類x的const成員變數

2. const成員函式。提到這個概念首先要談到const物件,正象內建型別能夠定義const物件一樣(const int r=10;),使用者自定義型別也可以定義const物件(const x px(10);),編譯器要保證這個物件在其生命週期內不能夠被改變。如果你定義了這樣的乙個const物件,那麼對於這個物件的一切非const成員函式的呼叫,編譯器為了保證物件的const特性,都會禁止並在編譯期間報錯。所以如果你想讓你的成員函式能夠在const物件上進行操作的話,就要把這個函式宣告為const成員函式。假如f( )是類中的成員函式的話,它的宣告形如:

int f( ) const; //const放在函式的最後,編譯器會對這個函式進行檢查,在這個函式中的任何試圖改變成員變數和呼叫非const成員函式的操作都被視為非法

**類的構造和析構函式都不能是const函式。

3. 建立了乙個const成員函式,但仍然想用這個函式改變物件內部的資料。這樣的乙個要求也會經常遇到,尤其是在乙個苛刻的面試考官那裡。首先我們要弄清楚考官的要求,因為有兩種方法可以實現,如果這位考官要求不改變原來類的任何東西,只讓你從當前這個const成員函式入手,那麼你只有使用前面提到的型別強制轉換方法。例項如下:

//假如有乙個叫做x的類,它有乙個int成員變數r,我們需要通過乙個const成員函式f( )來對這個r進行++r操作,**如下

void x::f( ) const

//通過this指標進行型別強制轉換實現

另外一種方法就是使用關鍵字:mutable 。 如果你的成員變數在定義時是這個樣子的:

mutable int r ;

那麼它就告訴編譯器這個成員變數可以通過const成員函式改變。編譯器就不會再理會對他的檢查了。 

c 中對const的總結

c 中const總結 對於基本宣告 1.const int r 100 標準const變數宣告加初始化,因為預設內部連線所以必須被初始化,其作用域為此檔案,編譯器經過型別檢查後直接用100在編譯時替換 2.extend const int r 100 將const改為外部連線,作用於擴大至全域性,編...

c 中對const的總結

c 中const總結 對於基本宣告 1.const int r 100 標準const變數宣告加初始化,因為預設內部連線所以必須被初始化,其作用域為此檔案,編譯器經過型別檢查後直接用100在編譯時替換 2.extend const int r 100 將const改為外部連線,作用於擴大至全域性,編...

C 中的const總結

這幾天看了c 程式設計思想,想把const的用法給總結一下 const的幾種用法如下 一.用做值替代.1 用來定義常量如 const int a 10 二.指標.1 指 const char p hello char const p hello 這兩種結果是一樣的,只是形式上不一樣.const 資料...