數據成員能夠分靜態變量、非靜態變量兩種.
靜態成員:靜態類中的成員加入static修飾符,便是靜態成員.能夠直接使用類名+靜態成員名訪問此靜態成員,由於靜態成員存在於內存,非靜態成員須要實例化纔會分配內存,因此靜態成員不能訪問非靜態的成員..由於靜態成員存在於內存,因此非靜態成員能夠直接訪問類中靜態的成員. 安全
非成靜態員:全部沒有加Static的成員都是非靜態成員,當類被實例化以後,能夠經過實例化的類名進行訪問。非靜態成員的生存期決定於該類的生存期..而靜態成員則不存在生存期的概念,由於靜態成員始終駐留在內容中。函數
一個類中也能夠包含靜態成員和非靜態成員,類中也包括靜態構造函數和非靜態構造函數。
spa
在C++中,靜態成員是屬於整個類的而不是某個對象,靜態成員變量只存儲一份供全部對象共用。因此在全部對象中均可以共享它。使用靜態成員變量實現多個對象之間的數據共享不會破壞隱藏的原則,保證了安全性還能夠節省內存。
靜態成員的定義或聲明要加個關鍵static。靜態成員能夠經過雙冒號來使用即<類名>::<靜態成員名>。對象
class Point { public: void init() { } static void output() { } }; int main(void) { Point::init(); Point::output(); }
編譯出錯:error C2352: 'Point::init' : illegal call of non-static member function
結論1:不能經過類名來調用類的非靜態成員函數。blog
經過類的對象調用靜態成員函數和非靜態成員函數內存
int main(void) { Point pt; pt.init(); pt.output(); }
編譯經過。
結論2:類的對象可使用靜態成員函數和非靜態成員函數。it
在類的靜態成員函數中使用類的非靜態成員#include <stdio.h> class Point io
{ public: void init() { } static void output() { printf("%d\n", m_x); } private: int m_x; }; int main() { Point pt; pt.output();
}
在類的靜態成員函數中使用類的非靜態成員
編譯出錯:error C2597: illegal reference to data member 'Point::m_x' in a static member function
由於靜態成員函數屬於整個類,在類實例化對象以前就已經分配空間了,而類的非靜態成員必須在類實例化對象後纔有內存空間,因此這個調用就出錯了,就比如沒有聲明一個變量卻提早使用它同樣。
結論3:靜態成員函數中不能引用非靜態成員。編譯
在類的非靜態成員函數中使用類的靜態成員: function
class Point { public: void init() { output(); } static void output() { } }; int main() { Point pt; pt.output(); return 0; }
編譯經過。
結論4:類的非靜態成員函數能夠調用用靜態成員函數,但反之不能。
使用類的靜態成員變量:
#include <stdio.h> class Point { public: Point() { m_nPointCount++; } ~Point() { m_nPointCount--; } static void output() { printf("%d\n", m_nPointCount); } private: static int m_nPointCount; }; int main() { Point pt; pt.output(); return 0; }
編譯無錯誤,生成EXE程序時報連接錯誤。
error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)
這是由於類的靜態成員變量在使用前必須先初始化。
在main()函數前加上int Point::m_nPointCount = 0;
再編譯連接無錯誤,運行程序將輸出1。
結論5:類的靜態成員變量必須先初始化再使用。
結合上面的五個例子,對類的靜態成員變量和成員函數做個總結:
一. 靜態成員函數中不能調用非靜態成員。
二. 非靜態成員函數中能夠調用靜態成員。由於靜態成員屬於類自己,在類的對象產生以前就已經存在了,因此在非靜態成員函數中是能夠調用靜態成員的。
三. 靜態成員變量使用前必須先初始化(如int MyClass::m_nNumber = 0;),不然會在linker時出錯。