天天看點

類的成員變量初始化總結

1. C++變量的初始化方式

首先把需要初始化的成員變量分為幾類:

Ø  一般變量(int)

Ø  靜态成員變量(static int)

Ø  常量(const int )

Ø  靜态常量(static const int)

 對應的初始化方式是:

Ÿ  一般變量可以在初始化清單裡或者構造函數裡初始化,不能直接初始化或者類外初始化

Ÿ  靜态成員變量必須在類外初始化

Ÿ  常量必須在初始化清單裡初始化

Ÿ  靜态常量必須隻能在定義的時候初始化(定義時直接初始化)

舉一個簡單的例子:

[cpp] view plain copy

  1. #include <iostream>   
  2. #include <string>   
  3. using namespace std;   
  4. class Test   
  5. {   
  6. private:   
  7.     int a;   
  8.     static int b;   
  9.     const int c;   
  10.     static const int d=4;   
  11. public:   
  12.     Test():c(3)     //a(1)或者在初始化清單裡初始化   
  13.     {   
  14.         a=1;   
  15.     }   
  16. };   
  17. int Test::b=2;  
  18. void main()   
  19. {   
  20.     Test t;   
  21. }  

2. 類成員變量初始化順序

C++

有如下幾條:

1構造函數初始化清單的變量優先于構造函數(至少明顯的寫在前面)  (若都在初始化清單中初始化,則按聲明順序初始化,與初始化清單中的順序無關)

2靜态成員變量先于執行個體變量

3父類成員變量先于子類成員變量

4父類構造函數先于子類構造函數

 舉一個例子:

[cpp] view plain copy

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4. class Test  
  5. {  
  6. public:  
  7.     Test(string n)  
  8.     {  
  9.         cout<<n<<endl;  
  10.     }  
  11. };  
  12. class Base  
  13. {  
  14. public:  
  15.     static Test* a;  
  16.     Test* b;  
  17.     Test* c;  
  18.     Base():b(new Test("b"))  
  19.     {  
  20.         c=new Test("c");  
  21.     }  
  22.     virtual ~Base()  
  23.     {  
  24.         if(a) delete a;//似乎是很欠妥的做法  
  25.         if(b) delete b;  
  26.         if(c) delete c;  
  27.     }  
  28. };  
  29. Test* Base::a=new Test("a");  
  30. class Derived:Base  
  31. {  
  32. public:  
  33.     static Test* da;  
  34.     Test* db;  
  35.     Test* dc;  
  36.     Derived():db(new Test("db"))  
  37.     {  
  38.         dc=new Test("dc");  
  39.     }  
  40.     ~Derived()  
  41.     {  
  42.         if(da) delete da;//似乎是很欠妥的做法  
  43.         if(db) delete db;  
  44.         if(dc) delete dc;  
  45.     }  
  46. };  
  47. Test* Derived::da=new Test("da");  
  48. void main()  
  49. {  
  50.     Derived d;  
  51. }  

結果是:

a

da

b

c

db

dc

java和C#語言

1   類成員變量初始化先于類的構造函數

2   靜态成員變量先于執行個體變量

3   父類成員變量先于子類成員變量 (C#相反)

4   父類構造函數先于子類構造函數

舉一個java的例子:

[java] view plain copy

  1. class Base  
  2. {  
  3.     public static Test a=new Test("a");  
  4.     public static Test b;  
  5.     public Test c=new Test("c");  
  6.     public Test d;  
  7.     static  
  8.     {  
  9.         b=new Test("b");  
  10.     }  
  11.     public Base()  
  12.     {  
  13.         d=new Test("d");  
  14.     }  
  15.     public static void main(String[] args) {  
  16.         new Derived();  
  17.     }  
  18. }  
  19. class Derived extends Base  
  20. {  
  21.     public static Test da=new Test("da");  
  22.     public static Test db;  
  23.     public Test dc=new Test("dc");  
  24.     public Test dd;  
  25.     static  
  26.     {  
  27.         db=new Test("db");  
  28.     }  
  29.     public Derived()  
  30.     {  
  31.         dd=new Test("dd");  
  32.     }  
  33. }  
  34. class Test  
  35. {  
  36.     public Test (String name) {  
  37.         System.out.println(name);  
  38.     }  
  39. }  

運作結果是:

a

b

da

db

c

d

dc

dd

C++ static、const和static const 以及它們的初始化

       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. int Test::b=0;//static成員變量不能在構造函數初始化清單中初始化,因為它不屬于某個對象。  
  12. 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. int foo::i=20;  
  9. 這表明:  
  10. 1、初始化在類體外進行,而前面不加static,以免與一般靜态變量或對象相混淆  
  11. 2、初始化時不加該成員的通路權限控制符private、public等  
  12. 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();//通過對象通路靜态成員函數