(1)為什麼需要類靜態成員?
有時候某個類的多個對象需要訪問一個全局對象,在這種情況下“提供一個全局對象”比“每個類都維持一個獨立的數據成員”要更為有效。而類靜態成員與全局變量相比,又有兩點好處:(a)不存在與程序中其他全局名字沖突的可能性;(b)可設置為private,實現信息隱藏。
(2)類靜態成員的特點
對於非靜態數據成員,每個類對象都有自己的拷貝,而靜態數據成員對每個類類型只有一個拷貝。由於靜態數據成員分配在全局數據區,因此在程序開始運行時就必須存在,故靜態數據成員的空間分配和初始化不可能在main函數或其他函數中完成(因而在局部類中也不允許出現靜態數據成員)。這樣一來,靜態數據成員的空間分配和初始化只可能有以下三種途徑:(a)類的頭文件:這裡有類的聲明。但存在一個無法回避的問題:對於靜態數據成員,在程序中也只能存在一個定義,而類的頭文件可能被重復引用而出現重復定義;(b)main函數前的全局數據聲明和定義處:這種方法也有問題,每一個使用該類的程序都必須在此處定義一下該類的靜態成員,這是不現實的;(c)類定義的內部實現:這是最為理想的方式,引用時只需包含頭文件即可。
#include "account.h"
double Account::_interestRate = 0.05
(3)類靜態成員的定義
在對靜態數據成員進行定義時有以下幾點注意事項:(a)在類定義之外定義時,靜態成員的名字必須被其類名限定修飾,前不可再添加static;(b)像int等有序類型的靜態數據成員可在類定義中初始化,但仍需在類定義外進行定義,但此時已不能指定初始值;
// 頭文件
class Account
{
// ...
private:
static const int nameSize = 16;
static const char name[nameSize];
};
// 文本文件
const int Account::nameSize; // 必需的成員定義,此處不可再進行初始化
const char Account::name[nameSize] = "Saving Account";
(4) 類靜態成員的訪問:
在類的成員函數中可以直接訪問該類的靜態數據成員,而在非成員函數中可使用成員訪問操作符或類名限定修飾的方式進行訪問。
(5)靜態成員函數:
靜態成員函數無法訪問屬於具體類對象的非靜態數據成員,也無法訪問非靜態成員函數,他只能訪問靜態數據成員和調用其余的靜態成員函數。這樣一來,就能防止類的非靜態數據成員遭受竄改。靜態成員函數沒有this指針,任何在靜態成員函數中顯式或隱式地引用這個指針都將導致編譯時刻錯誤。