1. 程式人生 > >C++靜態數據成員與靜態成員函數

C++靜態數據成員與靜態成員函數

class clas 有一個 失敗 end idt c++ 系統 構造

一般情況下,如果有n個同類的對象,那麽每一個對象都分別有自己的數據成員,不同對象的數據成員各自有值,互不相幹。但是有時人們希望有某一個或幾個數據成員為所有對象所共有,這樣可以實現數據共享。

可以使用全局變量來達到共享數據的目的。例如在一個程序文件中有多個函數,每一個函數都可以改變全局變量的值,全局變量的值為各函數共享。但是用全局變量的安全性得不到保證,由於在各處都可以自由地修改全局變量的值,很有可能偶然失誤,全局變量的值就被修改,導致程序的失敗。因此在實際工作中很少使用全局變量。

如果想在同類的多個對象之間實現數據共享,也不要用全局對象,可以用靜態的數據成員。

靜態數據成員

靜態數據成員是一種特殊的數據成員。它以關鍵字static開頭。例如

  1. class Box
  2. {
  3. public :
  4. int volume( );
  5. private :
  6. static int height; //把height定義為靜態的數據成員
  7. int width;
  8. int length;
  9. };

如果希望各對象中的height的值是一樣的,就可以把它定義為靜態數據成員,這樣它就為各對象所共有,而不只屬於某個對象的成員,所有對象都可以引用它。

靜態的數據成員在內存中只占一份空間。每個對象都可以引用這個靜態數據成員。靜態數據成員的值對所有對象都是一樣的。如果改變它的值,則在各對象中這個數據成員的值都同時改變了。這樣可以節約空間,提高效率。

關於靜態數據成員的幾點說明:
1) 如果只聲明了類而未定義對象,則類的一般數據成員是不占內存空間的,只有在定義對象時,才為對象的數據成員分配空間。但是靜態數據成員不屬於某一個對象,在為對象所分配的空間中不包括靜態數據成員所占的空間。靜態數據成員是在所有對象之外單獨開辟空間。只要在類中定義了靜態數據成員,即使不定義對象,也為靜態數據成員分配空間,它可以被引用。

在一個類中可以有一個或多個靜態數據成員,所有的對象共享這些靜態數據成員,都可以引用它。

2) 對於靜態變量,如果在一個函數中定義了靜態變量,在函數結束時該靜態變量並不釋放,仍然存在並保留其值。靜態數據成員也類似,它不隨對象的建立而分配空間,也不隨對象的撤銷而釋放(一般數據成員是在對象建立時分配空間,在對象撤銷時釋放)。靜態數據成員是在程序編譯時被分配空間的,到程序結束時才釋放空間。

3) 靜態數據成員可以初始化,但只能在類體外進行初始化。如
int Box::height=10; //表示對Box類中的數據成員初始化
其一般形式為:
數據類型類名::靜態數據成員名=初值;
不必在初始化語句中加static。

註意,不能用參數對靜態數據成員初始化。如在定義Box類中這樣定義構造函數是錯誤的:
Box(int h,int w,int len):height(h){ } //錯誤,height是靜態數據成員

如果未對靜態數據成員賦初值,則編譯系統會自動賦予初值0。

4) 靜態數據成員既可以通過對象名引用,也可以通過類名來引用。請觀察下面的程序。

[例9.10] 引用靜態數據成員。

  1. #include <iostream>
  2. using namespace std;
  3. class Box
  4. {
  5. public:
  6. Box(int,int);
  7. int volume( );
  8. static int height; //把height定義為公用的靜態的數據成員
  9. int width;
  10. int length;
  11. };
  12. Box::Box(int w,int len) //通過構造函數對width和length賦初值
  13. {
  14. width=w;
  15. length=len;
  16. }
  17. int Box::volume( )
  18. {
  19. return(height*width*length);
  20. }
  21. int Box::height=10; //對靜態數據成員height初始化
  22. int main( )
  23. {
  24. Box a(15,20),b(20,30);
  25. cout<<a.height<<endl; //通過對象名a引用靜態數據成員
  26. cout<<b.height<<endl; //通過對象名b引用靜態數據成員
  27. cout<<Box::height<<endl; //通過類名引用靜態數據成員
  28. cout<<a.volume( )<<endl; //調用volume函數,計算體積,輸出結果
  29. }

上面3個輸出語句的輸出結果相同(都是10)。這就驗證了所有對象的靜態數據成員實際上是同一個數據成員。

請註意,在上面的程序中將height定義為公用的靜態數據成員,所以在類外可以直接引用。可以看到在類外可以通過對象名引用公用的靜態數據成員,也可以通過類名引用靜態數據成員。即使沒有定義類對象,也可以通過類名引用靜態數據成員。這說明靜態數據成員並不是屬於對象的,而是屬於類的,但類的對象可以引用它。如果靜態數據成員被定義為私有的,則不能在類外直接引用,而必須通過公用的成員函數引用。

5) 有了靜態數據成員,各對象之間的數據有了溝通的渠道,實現數據共享,因此可以不使用全局變量。全局變量破壞了封裝的原則,不符合面向對象程序的要求。但是也要註意公用靜態數據成員與全局變量的不同,靜態數據成員的作用域只限於定義該類的作用域內(如果是在一個函數中定義類,那麽其中靜態數據成員的作用域就是此函數內)。在此作用域內,可以通過類名和域運算符“::”引用靜態數據成員,而不論類對象是否存在。

C++靜態數據成員與靜態成員函數