靜態類成員:是那些與類本身有關的成員數據和成員函數,而不是與該類對象相關的成員數據和成員函數。
所以靜態成員數據也稱為類數據,靜態成員函數也稱為類方法。靜態成員數據在類裡只是一個說明,還需要一個定義(或叫初始化)。靜態成員數據要在類定義之外被初始化(要用類名限定修飾),而且程序裡只能提供一次,所以初始化不能放在頭文件裡。
例1:
[cpp]
class Test{
public:
static int k;
Test(int a):k(a){ //編譯錯誤!!!
}
};
[cpp]
//error: 'int Test::k' is a static data member; it can only be initialized at its definition
例2:
C++規定const靜態類成員可以直接初始化,其他非const的靜態類成員需要在類聲明以外初始化,我們一般選擇在類的實現文件中初始化。
[cpp]
int Test::k;
默認初始化為0;
也可自己指定:
[cpp]
int Test::k(20);
[cpp] view plaincopy
class Test{
public:
static const int a = 10;
static int k;
};
int Test::k;
int main(){
cout << Test::k << endl;
cout << Test::a;
return 0;
}
•在inline函數裡不要使用靜態成員數據,因為編譯器不能保證此時靜態成員數據已初始化。
[cpp]
class Test{
public:
static const int a = 10;
static int k;
void f(){
k++;
}
};
int Test::k(20);
int main(){
Test t;
t.f();
cout << Test::k;
return 0;
}
[cpp]
class A{
public:
A(A & e):_e3(e){}
A & _e3;
A * _e1;
static A _e;
A _e2; // error C2460: '_e2' : uses 'A', which is being defined
};
•靜態成員數據與全局變量的比較:靜態成員數據不論類由多少實例,它都只有一個拷貝,這和全局變量類似。但靜態成員數據有個作用域名字,而且不一定是public的。
•靜態成員函數不能聲明為const和volatile。
•靜態成員函數和友元函數比較:靜態成員函數和友元函數都沒有隱含的this指針,且都能訪問類的private和protected部分。但靜態成員函數有個作用域名字,而且不一定是public的。
•const靜態成員數據:在有些C++編譯器裡,有序型的(如int,unsignedlong,char等)const靜態成員數據可以
在類裡對其初始化。
•靜態成員數據初始化次序:靜態初始化成員數據次序和類作用域的靜態對象、文件作用域和名字空間作用域的對象的生存周期有關。當在不同編譯單元(即.cpp文件)的靜態初始化有次序依賴,這就有可能有危險。解決的辦法將靜態成員數據轉換為靜態成員函數。
•volatile:當一個對象的值可能會在編譯器的控制或監視之外被改變,那該對象應該聲明為volatile。 此時編譯器執行的一些例行優化對它不能應用。volatile也可以修飾類成員函數。對於volatile類對象它只能調用volatile成員函數、構造函數和析構函數。