C++靜態數據成員與靜態成員函數
一般情況下,如果有n個同類的對象,那麽每一個對象都分別有自己的數據成員,不同對象的數據成員各自有值,互不相幹。但是有時人們希望有某一個或幾個數據成員為所有對象所共有,這樣可以實現數據共享。
可以使用全局變量來達到共享數據的目的。例如在一個程序文件中有多個函數,每一個函數都可以改變全局變量的值,全局變量的值為各函數共享。但是用全局變量的安全性得不到保證,由於在各處都可以自由地修改全局變量的值,很有可能偶然失誤,全局變量的值就被修改,導致程序的失敗。因此在實際工作中很少使用全局變量。
如果想在同類的多個對象之間實現數據共享,也不要用全局對象,可以用靜態的數據成員。
靜態數據成員
靜態數據成員是一種特殊的數據成員。它以關鍵字static開頭。例如
- class Box
- {
- public :
- int volume( );
- private :
- static int height; //把height定義為靜態的數據成員
- int width;
- int length;
- };
如果希望各對象中的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] 引用靜態數據成員。
- #include <iostream>
- using namespace std;
- class Box
- {
- public:
- Box(int,int);
- int volume( );
- static int height; //把height定義為公用的靜態的數據成員
- int width;
- int length;
- };
- Box::Box(int w,int len) //通過構造函數對width和length賦初值
- {
- width=w;
- length=len;
- }
- int Box::volume( )
- {
- return(height*width*length);
- }
- int Box::height=10; //對靜態數據成員height初始化
- int main( )
- {
- Box a(15,20),b(20,30);
- cout<<a.height<<endl; //通過對象名a引用靜態數據成員
- cout<<b.height<<endl; //通過對象名b引用靜態數據成員
- cout<<Box::height<<endl; //通過類名引用靜態數據成員
- cout<<a.volume( )<<endl; //調用volume函數,計算體積,輸出結果
- }
上面3個輸出語句的輸出結果相同(都是10)。這就驗證了所有對象的靜態數據成員實際上是同一個數據成員。
請註意,在上面的程序中將height定義為公用的靜態數據成員,所以在類外可以直接引用。可以看到在類外可以通過對象名引用公用的靜態數據成員,也可以通過類名引用靜態數據成員。即使沒有定義類對象,也可以通過類名引用靜態數據成員。這說明靜態數據成員並不是屬於對象的,而是屬於類的,但類的對象可以引用它。如果靜態數據成員被定義為私有的,則不能在類外直接引用,而必須通過公用的成員函數引用。
5) 有了靜態數據成員,各對象之間的數據有了溝通的渠道,實現數據共享,因此可以不使用全局變量。全局變量破壞了封裝的原則,不符合面向對象程序的要求。但是也要註意公用靜態數據成員與全局變量的不同,靜態數據成員的作用域只限於定義該類的作用域內(如果是在一個函數中定義類,那麽其中靜態數據成員的作用域就是此函數內)。在此作用域內,可以通過類名和域運算符“::”引用靜態數據成員,而不論類對象是否存在。
C++靜態數據成員與靜態成員函數