類是C++為程序員提供的定義新的數據類型的工具。數據類型規定了能對該類型的對象執行什麼操作。關於這個內容,我們在前麵已作了討論。本章將繼續介紹類的另外一些特性:類的靜態成員,const成員及友員。

7.1靜態成員

在定義一個類的時候,如果用於記錄某一因素的變量是經常發生變化的;對於這樣的變量,如果把它定義成為該類的一個成員,那麼該類的每個對象中就都會有它的一份拷貝。這不僅浪費空間,而且每當它發生變化時,就要更新多個對象。這樣做顯然是低效的,並且還有可能導致數據的不一致性。但是,如果把這種變量定義為一個全局變量,那麼,每個函數就都能修改它的值了。我們所需要的是一種僅僅適用於某個類的全局變量,對於這種情況,C++提供了一個解決辦法,就是允許將類的一個成員聲明為static(靜態的)。

在類中,使用關鍵字static修飾的類成員稱為靜態成員。如果所修飾的是數據成員,則稱為靜態數據成員;如果所修飾的是成員函數,則稱為靜態成員函數。

靜態成員也像類中說明的其它成員一樣,在訪問時受說明它的訪問權限的限製。如果是私有的,它就僅能被類中的成員函數訪問。如果是公有的,它不僅能被類中的成員函數所調用,還能在程序的其它地方調用。

一、靜態數據成員

靜態數據成員是一個靜態數據,它具有靜態數據的特性:在程序運行時就存在,而在程序結束時才被刪除。並且,當一個數據成員為靜態時,不管聲明了它所屬類的多少對象,都僅分配它的一份拷貝。首先來看一個例子。

當一個Mycla類的對象被建立時,構造函數將全局變量Count增1,而當一個Myclass類的對象被撤銷時,析構函數將Count減1。由於全局變量Coum被初始化為0,所以它可以記錄當前存在多少個Myclass類的對象。

但在編寫C++程序時,應該盡量鱗少使用全局變量的個數。因為全局變量不符合麵向對象的思想,也不便於對程序的維護。

靜態數據成員有以下特性:

1.遵從一般的類成員的訪問規則。即如果此靜態數據成員是公有的,可被程序中類以外的其它函數調用。而如果是私有的,則僅能被類中的成員函數所調用。

2.靜態數據成員被該類的所有對象共享。

如例中,假設有Myclass類的兩個對象obi和ob2。

對於靜態數據成員Count,obi.Count和ob2.Count實際上是同一個變量,它們在內存中是同一塊區域,這一點與非靜態數據成員是不同的。

所以,我們可以把靜態數據成員理解為類的成員,而不是某一特定對象的成員。這樣,我們就可以通過下麵的形式訪問類的靜態數據成員了:類名:靜態數據成員如例中的Myclass::Count。

3.靜態數據成員具有全局性的生存期。即程序一運行,靜態數據成員就被分配內存,而直至程序運行結束。

4.靜態數據成員是類對象的一部分。我們可以通過該類的對象去訪問靜態數據成員。靜態數據成員除了具有上述幾點特性外,它還有以下幾點用法:

1.靜態數據成員在類中隻是進行了說明,我們還必須在程序的全局區把它定義一次,以便為其分配內存。定義時可以為其指定初始值,定義的一般格式為:

數據類型類名::靜態數據成員名=初始值;

如例中的intMyclass::Count=0;

2.訪問靜態數據成員,最好使用下麵形式:

類名::靜態數據成員名

3.在類的成員函數中,可以像其它數據成員一樣直接通過名字去訪何靜態數據。

4.如果對象存在,則允許該對象訪問靜態成員。格式為:對象名.靜態數據成員名。

5.在編寫C++程序時,盡量少用全局變量,而使用類的靜態數據成員,以符合麵向對象程序設計的思想。

二、靜態成員函數

在上例中,為了能在類以外的函數中訪問靜態成員Const,我們把它說明成公有的。但這一點也不符合麵向對象的程序設計思想。那麼,我們能不能既把靜態數據成員說明成私有的,也能達到同樣的效果呢?可以把Count說明成私有的靜態數據成員,然後再用一個公有的成員函數去訪問它。

但是,對於普通的成員函數,隻有在創建了具體的對象之後,才能通過它的對象去訪問成員函數。這一點又與靜態數據成員的存在不依賴於特定的類對象相矛盾。如何能在沒有任何對象被創建的情況下,去訪問靜態數據成員呢?解決這個矛盾的方法就是把這個成員函數定義成靜態的。

靜態成員函數有以下特性:

1.靜態成員函數不依賴具體的類的對象。即使沒有任何對象存在,也可以調用靜態成員函數。