C++中const總結

來源:互聯網
上載者:User

C++中const總結 

一:對於基本聲明 
1.const int r=100; 
//標準const變數聲明加初始化,因為預設內部串連所以必須被初始化,其範圍 
為此檔案,編譯器經過類型檢查後直接用100在編譯時間替換. 

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

3.const int r[]={1,2,3,4}; 
struct S {int a,b;}; 
const S s[]={(1,2),(3.4)}; 
//以上兩種都是常量集合,編譯器會為其分配記憶體,所以不能在編譯期間使用其中 
的值,例如: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 <int*> (&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 () { return CX(); } 
const CX Fuction2 () { return CX(); } 
如有上面的自訂類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 
{const_cast <X*> (this)-> ++r; } //通過this指標進行類型強制轉換實現 
另外一種方法就是使用關鍵字:mutable. 
如果你的成員變數在定義時是這個樣子的:mutable int r; 
那麼它就告訴編譯器這個成員變數可以通過const成員函數改變.編譯器就不會再 
理會對他的檢查了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.