c++的const和static區別

c++的const和static區別

const定義的常量在超出其作用域之後其空間會被釋放,而static定義的靜態常量在函數執行後不會釋放其存儲空間。

      static表示的是靜態的。類的靜態成員函數、靜態成員變量是和類相關的,而不是和類的具體對象相關的。即使沒有具體對象,也能調用類的靜態成員函數和成員變量。一般類的靜態函數幾乎就是一個全局函數,只不過它的作用域限於包含它的文件中。

      在C++中,static靜態成員變量不能在類的內部初始化。在類的內部只是聲明,定義必須在類定義體的外部,通常在類的實現文件中初始化,如:double Account::Rate=2.25;static關鍵字只能用於類定義體內部的聲明中,定義時不能標示爲static

      在C++中,const成員變量也不能在類定義處初始化,只能通過構造函數初始化列表進行,並且必須有構造函數。

      const數據成員 只在某個對象生存期內是常量,而對於整個類而言卻是可變的。因爲類可以創建多個對象,不同的對象其const數據成員的值可以不同。所以不能在類的聲明中初始化const數據成員,因爲類的對象沒被創建時,編譯器不知道const數據成員的值是什麼。

      const數據成員的初始化只能在類的構造函數的初始化列表中進行。要想建立在整個類中都恆定的常量,應該用類中的枚舉常量來實現,或者static cosnt。

 

[cpp] view plain copy

 

  1. class Test  
  2. {  
  3. public:  
  4.       Test():a(0){}  
  5.       enum {size1=100,size2=200};  
  6. private:  
  7.       const int a;//只能在構造函數初始化列表中初始化  
  8.        static int b;//在類的實現文件中定義並初始化  
  9.       const static int c;//與 static const int c;相同。  
  10. };  
  11.   
  12. int Test::b=0;//static成員變量不能在構造函數初始化列表中初始化,因爲它不屬於某個對象。  
  13. cosnt int Test::c=0;//注意:給靜態成員變量賦值時,不需要加static修飾符。但要加cosnt  

 

      cosnt成員函數主要目的是防止成員函數修改對象的內容。即const成員函數不能修改成員變量的值,但可以訪問成員變量。當方法成員函數時,該函數只能是const成員函數。

      static成員函數主要目的是作爲類作用域的全局函數。不能訪問類的非靜態數據成員。類的靜態成員函數沒有this指針,這導致:1、不能直接存取類的非靜態成員變量,調用非靜態成員函數2、不能被聲明爲virtual

關於static、const、static cosnt、const static成員的初始化問題:

1、類裏的const成員初始化:

在一個類裏建立一個const時,不能給他初值

 

[cpp] view plain copy

 

  1. class foo  
  2. {  
  3. public:  
  4.       foo():i(100){}  
  5. private:  
  6.       const int i=100;//error!!!  
  7. };  
  8. //或者通過這樣的方式來進行初始化  
  9. foo::foo():i(100)  
  10. {}  

 

2、類裏的static成員初始化:

      類中的static變量是屬於類的,不屬於某個對象,它在整個程序的運行過程中只有一個副本,因此不能在定義對象時 對變量進行初始化,就是不能用構造函數進行初始化,其正確的初始化方法是:

數據類型 類名::靜態數據成員名=值;

 

[c-sharp] view plain copy

 

  1. class foo  
  2. {  
  3. public:  
  4.       foo();  
  5. private:  
  6.       static int i;  
  7. };  
  8.   
  9. int foo::i=20;  
  10. 這表明:  
  11. 1、初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆  
  12. 2、初始化時不加該成員的訪問權限控制符private、public等  
  13. 3、初始化時使用作用域運算符來表明它所屬的類,因此,靜態數據成員是類的成員而不是對象的成員。  

 

3、類裏的static cosnt 和 const static成員初始化

      這兩種寫法的作用一樣,爲了便於記憶,在此值說明一種通用的初始化方法:

 

[cpp] view plain copy

 

  1. class Test  
  2. {  
  3. public:  
  4.       static const int mask1;  
  5.       const static int mask2;  
  6. };  
  7. const Test::mask1=0xffff;  
  8. const Test::mask2=0xffff;  
  9. //它們的初始化沒有區別,雖然一個是靜態常量一個是常量靜態。靜態都將存儲在全局變量區域,其實最後結果都一樣。可能在不同編譯器內,不同處理,但最後結果都一樣。  

 

這是一個完整的例子:

 

[cpp] view plain copy

 

  1. #ifdef A_H_  
  2. #define A_H_  
  3. #include <iostream>  
  4. using namespace std;  
  5. class A  
  6. {  
  7. public:  
  8.       A(int a);  
  9.       static void print();//靜態成員函數  
  10. private:  
  11.       static int aa;//靜態數據成員的聲明  
  12.        static const int count;//常量靜態數據成員(可以在構造函數中初始化)  
  13.        const int bb;//常量數據成員  
  14. };  
  15. int A::aa=0;//靜態成員的定義+初始化  
  16. const int A::count=25;//靜態常量成員定義+初始化  
  17. A::A(int a):bb(a)//常量成員的初始化  
  18. {  
  19.       aa+=1;  
  20. }  
  21. void A::print()  
  22. {  
  23.       cout<<"count="<<count<<endl;  
  24.       cout<<"aa="<<aa<<endl;  
  25. }  
  26. #endif  
  27. void main()  
  28. {  
  29.       A a(10);  
  30.       A::print();//通過類訪問靜態成員函數  
  31.       a.print();//通過對象訪問靜態成員函數  
  32. }  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章