1. 程式人生 > >static作用

static作用

靜態成員如果有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 引用靜態資料成員。
    cout<<a.height<<endl; 通過物件名a引用靜態資料成員
    cout<<b.height<<endl; 通過物件名b引用靜態資料成員
    cout<<box::height<<endl; 通過類名引用靜態資料成員
    cout<<a.volume( )<<endl;="" 呼叫volume函式,計算體積,輸出結果}
    上面3個輸出語句的輸出結果相同(都是10)。這就驗證了所有物件的靜態資料成員實際上是同一個資料成員。

    請注意: 在上面的程式中將height定義為公用的靜態資料成員,所以在類外可以直接引用。可以看到在類外可以通過物件名引用公用的靜態資料成員,也可以通過類名引用靜態資料成員。即使沒有定義類物件,也可以通過類名引用靜態資料成員。這說明靜態資料成員並不是屬於物件的,而是屬於類的,但類的物件可以引用它。

    如果靜態資料成員被定義為私有的,則不能在類外直接引用,而必須通過公用的成員函式引用。
  5. 有了靜態資料成員,各物件之間的資料有了溝通的渠道,實現資料共享,因此可以不使用全域性變數。
    全域性變數破壞了封裝的原則,不符合面向物件程式的要求。但是也要注意公用靜態資料成員與全域性變數的不同,靜態資料成員的作用域只限於定義該類的作用域內(如果是在一個函式中定義類,那麼其中靜態資料成員的作用域就是此函式內)。在此作用域內,可以通過類名和域運算子“::”引用靜態資料成員,而不論類物件是否存在。