2.靜態成員函數的一般格式為:

3.如果存在具體的對象,當然可以通過對象去訪問靜態成員函數。格式為:對象名.靜態成員函數名(參數表)

4.在靜態成員函數中,隻能直接訪問類的靜態數據成員,而不能直接訪問類的非靜態數據成員。因為,訪問靜態成員函數無需依賴具體的對象,沒有對象存在時,也可以獨立調用靜態成員函數。因此,當編譯器調用靜態成員函數時,不會向它傳遞this指針。這樣,編譯器無法知道靜態成員函數中調用的非靜態數據成員是什麼。從本質上講,靜態成員函數並不是類的成員函數,原因在於它沒有隱含參數:this指針。

5.如果靜態成員函數是在類的說明體之外定義的,那麼定義時可以省略關鍵字static。

7.2const成員

在聲明一個類時,如果某一數據成員被const所修飾,則該數據成員被稱為const數據成員。同理,某一成員函數被const所修飾,則稱為const成員函數。

一、const數據成員

const是“不變”的意思,它被用來凍結一個變量,使其在程序中不能被改變。在說明一個const變量時,必須為其提供初始值,而不能用賦值語句給const變量賦值。這些限製同樣也適用於const數據成員。

但是,由於在類的說明中不允許為類的數據成員提供初始值,那麼該如何去初始化這個const數據成員呢?解決的辦法是使用初始化表。

其中,參數表和函數之間的a(i)就是成員初始化表。對成員初始化表,有如下說明:

1.成員初始化表隻能存在於構造函數中。

2.成員初始化表必須位於構造函數的參數表和構造函數的函數體之間,且與參數表之間用冒號隔開。

3.如果構造函數的函數體在類之外說明,則構造函數的函數原型後不能加人成員初始化表。如例7.4可寫成下麵的形式:

4.成員初始化表的格式為:數據成員名(值)

其中,值是要設定的初始值,它可以是構造函數參數表中的形式參數,也可以是常量值。如例7.4還可以寫成:

注意,在構造函數MyclassO中,由於ci使用常量值作為初始值,所以構造函數.Myclass()的參數為空。

5.如果有多個數據成員要通過初始化表初始化,則成員初始化表的各項應用逗號隔開。應該注意的是:每個數據成員名最多隻能出現一次。

7.由於在程序中不能對引用類型的變量賦值,隻能在說明該引用變量時提供初始值。因此,如果類的數據成員為引用類型,那麼該數據成員必須通過成員初始化表進行初始化。例如:

二、const成員函數

在聲明類的時候,對於有的成員函數,如果不希望它修改類的數據成員的值,就可以把該成員函數指定為court成員函數,說明的一般格式為:

對於本例中的Myclass類,成員函數Get()隻是返回數據成員value的值,並沒有對這個值進行修改。這時,我們就可以把它定義成const成員函數。這樣,編譯器就會自動檢查該成員函數,看它是否修改了類中的數據成員,若修改了,則會給出出錯信息。而對於成員函數Set(),由於它通過賦值語句value=v;修改了數據成員value的值,所以,對這樣的函數,我們就不能將它定義為const成員函數。請再看一個例子。

對於本例中的類Myclass,數據成員ptr是指針類型變量。在成員函數Good()中,雖然也有陚值語句*ptr=i;,但是此賦值語句的執行結果並沒有改變數據成員ptr本身的值。所以,我們還是可以把這樣的函數說明成const成員函數的。而成員函數Set()中,數據成員ptr被直接賦值,從而改變了它的值,所以,對這樣的函數就不能把它說明成const成員函數。

還要注意的一點就是:對於普通對象既可以訪問類中的const成員函數,也可以訪問類中的非const成員函數。而對於常量對象就隻能訪問類中的const成員函數,卻不能訪問類中的非const成員函數。這是因為,不能在程序中以任何方式改變常量的值。而非const成員函數卻可能修改類的數據成員,進而可能修改常量對象的數據成員。這顯然是不允許的。例如:

在本例中,說明了類Myclass的兩個對象ob和cob。ob被說明為普通對象,它對成員函數Set()和Get()的訪問都是允許的。而cob被說明為常量對象,那麼它對const成員函數Get()的訪問是允許的,而對非const成員函數Set()的訪問是不允許的。否則,cob.value的值將會被成員函數Set()所修改。