程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ const用法小結 (歡迎大家拍磚)

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

編輯:C++入門知識

const 是constant的縮寫,本意是不變的,不易改變的意思。   const 在C++中是用來修飾內置類型變量,自定義對象,成員函數,返回值,函數參數。       一、const修飾普通類型的變量。   如下:   1 const int  a = 7;  2  3 int  b = a; //it's right 4  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 right 6  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 changed 12  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 9 24  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()const 16  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()const 16  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 wrong 10         ++_ct; //it's right 11     } 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 }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved