1. 程式人生 > >C++靜態成員:靜態資料成員和靜態函式成員

C++靜態成員:靜態資料成員和靜態函式成員

由關鍵字static修飾說明的類成員,成為靜態類成員(static class member),包括:靜態資料成員靜態函式成員。類的靜態成員為其所有物件共享,不管有多少物件,靜態成員只有一份存於公用記憶體中。

雖然使用static修飾說明,但與函式中的靜態變數有明顯差異。

靜態資料成員

在類定義中,用關鍵字static修飾的資料成員為靜態資料成員。該類產生的所有物件共享系統為靜態成員分配的一個儲存空間,而這個儲存空間是在編譯時分配的,在定義物件時不再為靜態成員分配空間。靜態資料實際上是該類所有物件所共有的,它更像在面向過程程式設計時的全域性變數,可提供同一類的所有物件之間資訊交換的捷徑。

正因為靜態資料成員不屬於類的某一特定物件,而是屬於整個類的,所以使用時可用以下格式:
    類名::靜態資料成員名

【例4.9】用靜態資料成員計算由同一類建立的物件的數量。
#include <iostream.h>
class Ctest
{
private:
       static int count;//注意私有
public:
       Ctest()
       {
              ++count;
              cout<<"物件數量="<<count<<'/n';
       }
       ~Ctest()
       {
              –count;
              cout<<"物件數量="<<count<<'/n';
       }
};
int Ctest::count=0; //A行 對靜態資料成員的定義性說明 void main(void)
{
       Ctest a[3];
}

執行程式後輸出:
物件數量=1 //a[0]建構函式產生
物件數量=2 //a[1]建構函式產生
物件數量=3 //a[2]建構函式產生
物件數量=2 //a[2]解構函式產生
物件數量=1 //a[1]解構函式產生
物件數量=0 //a[0]解構函式產生

此例中A行是對靜態成員資料資料作定義性說明,必須在檔案作用域中作一次並只能做一次說明,只有在這時C++編譯器為靜態資料成員分配儲存空間。C++靜態資料成員預設的初值為0,所以A行中“=0”是可以省去的。

特別要注意不管靜態變數是私有或公有,定義性說明均有效。

靜態函式成員

◆ 1、函式成員說明為靜態,將與該類的不同物件無關。嚴格地講,在邏輯上該函式成員只有一個拷貝。

靜態函式成員的呼叫,在物件之外可以採用下面的方式: 類名::函式名

與靜態資料成員相反,為使用方便,靜態函式成員多為公有的。

【例4.8_2】與靜態資料成員相反,為使用方便,靜態函式成員多為公有的。在例4.8中的複數類中的函式成員print(),如被說明為靜態的則可如下表達:
static void print()
{
       cout<<”Real=”<<Real<<’/t’<<”Image=”<<Image<<’/n’;
}
因它是獨立於具體物件而存在的,似乎可以用complex::print( )來呼叫。但是因為資料不確定(C++系統不知應取哪一個物件的資料)而不能執行。

在本例中print()函式應改為:
static void print(complex & ob)
{
       cout<<”Real=”<<ob.Real<<’/t’<<”Image=”<<ob.Image<<’/n’ ;
}
這裡用complex的物件的引用為引數,而以具體的complex物件為實參,這樣就能正常運行了。

◆ 2、如果靜態成員函式在類定義之外定義時,則不能在定義時再加static,這一點與友元函式類似。因為static不屬於資料型別組成部分。

因為C++在產生類的物件時,為了減少物件所佔空間,物理上將同一類的所有物件的成員函式只保留一個拷貝,所以一般情況下定義靜態函式不能取得明顯好處,只有邏輯上的優點。反而在使用上變得不方便,通常是沒有必要去定義靜態成員函式的。