C++ const用法小結 (歡迎大家拍磚)

來源:互聯網
上載者:User

標籤:int   可變   函數   ios   ret   不可   tab   ola   oid   

 

C++const 關鍵字小結

 

const 是constant的縮寫,本意是不變的,不易改變的意思。

const 在C++中是用來修飾內建類型變數,自訂對象,成員函數,傳回值,函數參數

 

一、const修飾普通類型的變數。

如下:

1 const int  a = 7; 2 3 int  b = a; //it‘s right4 5 a = 8;       // it‘s wrong,

 

a被定義為一個常量,並且可以將a賦值給b,但是不能給a再次賦值。對一個常量賦值是違法的事情,因為a被編譯器認為是一個常量,其值不允許修改

接著看如下的操作:

 1   2  3 #include<iostream> 4  5 using namespace std; 6  7 int main(void) 8  9 {10 11     const int  a = 7;12 13     int  *p = (int*)&a;14 15     *p = 8;16 17     cout<<a;18 19     system("pause");20 21     return 0;22 23 }

 

對於const變數a,我們取變數的地址並轉換賦值給 指向int的指標,然後利用*p = 8;重新對變數a地址內的值賦值,然後輸出查看a的值。

從下面的調試視窗看到a的值被改變為8,但是輸出的結果仍然是7。

 

 

 

從結果中我們可以看到,編譯器然後認為a的值為一開始定義的7,所以對const  a的操作就會產生上面的情況。所以千萬不要輕易對const變數設法賦值,這會產生意想不到的行為。

如果不想讓編譯器察覺到上面到對const的操作,我們可以在const前面加上volatile關鍵字

Volatile關鍵字跟const對應相反,是易變的,容易改變的意思。所以不會被編譯器最佳化,編譯器也就不會改變對a變數的操作。

 

 1 #include<iostream> 2  3 using namespace std; 4  5 int main(void) 6  7 { 8  9     volatile const int  a = 7;10 11     int  *p = (int*)&a;12 13     *p = 8;14 15     cout<<a;16 17     system("pause");18 19     return 0;20 21 }

輸出結果如我們期望的是8

 

二、const 修飾指標變數。

const 修飾指標變數有以下三種情況。

 

A:const 修飾指標指向的內容,則內容為不可變數。

B:const 修飾指標,則指標為不可變數。

C:const 修飾指標和指標指向的內容,則指標和指標指向的內容都為不可變數。

 

對於A: 

  1 const int *p = 8; 

//則指標指向的內容8不可改變。簡稱左定值,因為const位於*號的左邊

 

對於B:

1  int a = 8;2  3  int* const p = &a;4 5  *p = 9; //it’s right6 7  int  b = 7;8 9  p = &b; //it’s wrong

//對於const指標p其指向的記憶體位址不能夠被改變,但其內容可以改變。簡稱,右定向。因為const位於*號的右邊

 

對於C:

則是A和B的合并,

1 int a = 8;2 3 const int * const  p = &a;4 5  

 

//這時,const p的指向的內容和指向的記憶體位址都已固定,不可改變。

 

對於A,B,C三種情況,根據const位於*號的位置不同,我總結三句話便於記憶的話,

“左定值,右定向,const修飾不變數”

 

三、const參數傳遞和函數傳回值。

 

對於const修飾函數參數可以分為三種情況。

A:值傳遞的const修飾傳遞,一般這種情況不需要const修飾,因為函數會自動產生臨時變數複製實參值。

 1 #include<iostream> 2  3 using namespace std; 4  5 void Cpf(const int a) 6  7 { 8  9     cout<<a;10 11     // ++a;  it‘s wrong, a can‘t is changed12 13 }14 15 int main(void)16 17 {18 19     Cpf(8);20 21     system("pause");22 23     return 0;24 25 }

 

B:當const參數為指標時,可以防止指標被意外篡改。

 1 #include<iostream> 2  3 using namespace std; 4  5 void Cpf(int *const a) 6  7 { 8  9     cout<<*a<<" ";10 11     *a = 9;12 13 }14 15 int main(void)16 17 {18 19     int a = 8;20 21     Cpf(&a);22 23     cout<<a; // a is 924 25     system("pause");26 27     return 0;28 29 }

 

C:自訂類型的參數傳遞,需要臨時對象複製參數,對於臨時對象的構造,需要調用建構函式,比較浪費時間,因此我們採取const外加引用傳遞的方法。

並且對於一般的int ,double等內建類型,我們不採用引用的傳遞方式。

 1 #include<iostream> 2  3 using namespace std; 4  5 class Test 6  7 { 8  9 public:10 11     Test(){}12 13     Test(int _m):_cm(_m){}14 15     int get_cm()const16 17     {18 19        return _cm;20 21     }22 23 private:24 25     int _cm;26 27 };28 29  30 31 void Cmf(const Test& _tt)32 33 {34 35     cout<<_tt.get_cm();36 37 }38 39 int main(void)40 41 {42 43     Test t(8);44 45     Cmf(t);46 47     system("pause");48 49     return 0;50 51 }

//結果輸出 8

 

對於const修飾函數的傳回值

Const修飾傳回值分三種情況。

A:const修飾內建類型的傳回值,修飾與不修飾傳回值作用一樣。

 1 #include<iostream> 2  3 using namespace std; 4  5 const int Cmf() 6  7 { 8  9     return 1;10 11 }12 13 int Cpf()14 15 {16 17     return 0;18 19 }20 21 int main(void)22 23 {24 25     int _m = Cmf();26 27     int _n = Cpf();28 29  30 31     cout<<_m<<" "<<_n;32 33     system("pause");34 35     return 0;36 37 }

 

B:const 修飾自訂類型的作為傳回值,此時返回的值不能作為左值使用,既不能被賦值,也不能被修改。

 

C: const 修飾返回的指標或者引用,是否返回一個指向const的指標,取決於我們想讓使用者幹什麼。

 

 

四、const修飾類成員函數.

const 修飾類成員函數,其目的是防止成員函數修改被調用對象的值,如果我們不想修改一個調用對象的值,所有的成員函數都應當聲明為const成員函數。注意:const關鍵字不能與static關鍵字同時使用,因為static關鍵字修飾靜態成員函數,靜態成員函數不含有this指標,即不能執行個體化,const成員函數必須具體到某一執行個體。

 

下面的get_cm()const;函數用到了const成員函數

 

 1 #include<iostream> 2  3 using namespace std; 4  5 class Test 6  7 { 8  9 public:10 11     Test(){}12 13     Test(int _m):_cm(_m){}14 15     int get_cm()const16 17     {18 19        return _cm;20 21     }22 23 private:24 25     int _cm;26 27 };28 29  30 31 void Cmf(const Test& _tt)32 33 {34 35     cout<<_tt.get_cm();36 37 }38 39 int main(void)40 41 {42 43     Test t(8);44 45     Cmf(t);46 47     system("pause");48 49     return 0;50 51 }

 

如果get_cm()去掉const修飾,則Cmf傳遞的const _tt即使沒有改變對象的值,編譯器也認為函數會改變對象的值,所以我們盡量按照要求將所有的不需要改變對象內容的函數都作為const成員函數。

 

 如果有個成員函數想修改對象中的某一個成員怎麼辦?這時我們可以使用mutable關鍵字修飾這個成員,mutable的意思也是易變的,容易改變的意思,被mutable關鍵字修飾的成員可以處於不斷變化中,如下面的例子。

 

 1 #include<iostream> 2 using namespace std; 3 class Test 4 { 5 public: 6     Test(int _m,int _t):_cm(_m),_ct(_t){} 7     void Kf()const 8     { 9         ++_cm; //it‘s wrong10         ++_ct; //it‘s right11     }12 private:13     int _cm;14     mutable int _ct;15 };16 17 int main(void)18 {19     Test t(8,7);20     return 0;21 }

 

這裡我們在Kf()const中通過++_ct;修改_ct的值,但是通過++_cm修改_cm則會報錯。因為++_cm沒有用mutable修飾

C++ 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.