靜態(tài)成員的定義或聲明要加個關(guān)鍵static。靜態(tài)成員可以通過雙冒號來使用即<類名>::<靜態(tài)成員名>。
在C++中類的靜態(tài)成員變量和靜態(tài)成員函數(shù)是個容易出錯的地方,本文先通過幾個例子來總結(jié)靜態(tài)成員變量和成員函數(shù)使用規(guī)則,再給出一個實例來加深印象。希望閱讀本文可以使讀者對類的靜態(tài)成員變量和成員函數(shù)有更為深刻的認識。
第一個例子,通過類名調(diào)用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)
[cpp] view plain copyclass Point { public: void init() { } static void output() { } }; void main() { Point::init(); Point::output(); }編譯出錯:error C2352: 'Point::init' : illegal call of non-static member function
結(jié)論1:不能通過類名來調(diào)用類的非靜態(tài)成員函數(shù)。
第二個例子,通過類的對象調(diào)用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)
將上例的main()改為:
[cpp] view plain copyvoid main() { Point pt; pt.init(); pt.output(); }編譯通過。
結(jié)論2:類的對象可以使用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)。
第三個例子,在類的靜態(tài)成員函數(shù)中使用類的非靜態(tài)成員
[cpp] view plain copy#include <stdio.h> class Point { public: void init() { } static void output() { PRintf("%d/n", m_x); } private: int m_x; }; void main() { Point pt; pt.output(); }編譯出錯:error C2597: illegal reference to data member 'Point::m_x' in a static member function
因為靜態(tài)成員函數(shù)屬于整個類,在類實例化對象之前就已經(jīng)分配空間了,而類的非靜態(tài)成員必須在類實例化對象后才有內(nèi)存空間,所以這個調(diào)用就出錯了,就好比沒有聲明一個變量卻提前使用它一樣。
結(jié)論3:靜態(tài)成員函數(shù)中不能引用非靜態(tài)成員。
第四個例子,在類的非靜態(tài)成員函數(shù)中使用類的靜態(tài)成員
[cpp] view plain copyclass Point { public: void init() { output(); } static void output() { } }; void main() { Point pt; pt.output(); }編譯通過。
結(jié)論4:類的非靜態(tài)成員函數(shù)可以調(diào)用用靜態(tài)成員函數(shù),但反之不能。
第五個例子,使用類的靜態(tài)成員變量
[cpp] view plain copy#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; }; void main() { Point pt; pt.output(); }按Ctrl+F7編譯無錯誤,按F7生成EXE程序時報鏈接錯誤
error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)
這是因為類的靜態(tài)成員變量在使用前必須先初始化。
在main()函數(shù)前加上int Point::m_nPointCount = 0;
再編譯鏈接無錯誤,運行程序?qū)⑤敵?。
結(jié)論5:類的靜態(tài)成員變量必須先初始化再使用。
結(jié)合上面的五個例子,對類的靜態(tài)成員變量和成員函數(shù)作個總結(jié):
一。靜態(tài)成員函數(shù)中不能調(diào)用非靜態(tài)成員。
二。非靜態(tài)成員函數(shù)中可以調(diào)用靜態(tài)成員。因為靜態(tài)成員屬于類本身,在類的對象產(chǎn)生之前就已經(jīng)存在了,所以在非靜態(tài)成員函數(shù)中是可以調(diào)用靜態(tài)成員的。
三。靜態(tài)成員變量使用前必須先初始化(如int MyClass::m_nNumber = 0;),否則會在linker時出錯。
再給一個利用類的靜態(tài)成員變量和函數(shù)的例子以加深理解,這個例子建立一個學生類,每個學生類的對象將組成一個雙向鏈表,用一個靜態(tài)成員變量記錄這個雙向鏈表的表頭,一個靜態(tài)成員函數(shù)輸出這個雙向鏈表。
[cpp] view plain copy#include <stdio.h> #include <string.h> const int MAX_NAME_SIZE = 30; class Student { public: Student(char *pszName); ~Student(); public: static void PrintfAllStudents(); private: char m_name[MAX_NAME_SIZE]; Student *next; Student *prev; static Student *m_head; }; Student::Student(char *pszName) { strcpy(this->m_name, pszName); //建立雙向鏈表,新數(shù)據(jù)從鏈表頭部插入。 this->next = m_head; this->prev = NULL; if (m_head != NULL) m_head->prev = this; m_head = this; } Student::~Student ()//析構(gòu)過程就是節(jié)點的脫離過程 { if (this == m_head) //該節(jié)點就是頭節(jié)點。 { m_head = this->next; } else { this->prev->next = this->next; this->next->prev = this->prev; } } void Student::PrintfAllStudents() { for (Student *p = m_head; p != NULL; p = p->next) printf("%s/n", p->m_name); } Student* Student::m_head = NULL; void main() { Student studentA("AAA"); Student studentB("BBB"); Student studentC("CCC"); Student studentD("DDD"); Student student("MoreWindows"); Student::PrintfAllStudents(); }程序?qū)⑤敵觯?/p>
當然在本例還可以增加個靜態(tài)成員變量來表示鏈表中學生個數(shù),如果讀者有興趣,就將這個作為小練習吧。
轉(zhuǎn)載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/6721430新聞熱點
疑難解答
圖片精選