【C++深度剖析教程5】C++中类的静态成员函数
- 學習交流加(可免費幫忙下載CSDN資源):
- 個人微信: liu1126137994
- 學習交流資源分享qq群1(已滿): 962535112
- 學習交流資源分享qq群2(已滿): 780902027
- 學習交流資源分享qq群3:893215882
在上一篇文章中我們講了C++中類的靜態成員變量,用類的靜態成員變量實現了統計程序運行期間的某個類的對象的數目(不清楚的可以點擊連接查看上一篇文章 C++中類的靜態成員變量)。
我們回顧一下客戶的需求:
- 統計在程序運行期間某個類的對象的數目
- 保證程序的安全性(不能使用全局變量)
- 隨時可以獲取當前對象的數目(完成了么?)
看當時的代碼:
#include <stdio.h>class Test { private:static int cCount; public:Test(){cCount++;}~Test(){--cCount;}int getCount(){return cCount;} };int Test::cCount = 0;Test gTest;int main() {Test t1;Test t2;printf("count = %d\n", gTest.getCount());printf("count = %d\n", t1.getCount());printf("count = %d\n", t2.getCount());Test* pt = new Test();printf("count = %d\n", pt->getCount());delete pt;printf("count = %d\n", gTest.getCount());return 0; }很明顯,我們獲取對象的數目是需要調用getCount這個函數,每次調用都需要某一個對象來調用,比如:gTest.getCount(),那么問題來了,如果整個程序的對象的個數為0呢?那么豈不是沒法調用getCount這個函數,也就沒法知道對象的個數(別人是不知道你的對象的個數為0的)?
可不可以這樣呢?我把靜態成員變量cCount變為public,然后直接讓Test(作用域調用)這個類來調用?先上一波代碼看看:
#include <stdio.h>class Test { public:static int cCount; public:Test(){cCount++;}~Test(){--cCount;}int getCount(){return cCount;} };int Test::cCount = 0;int main() {printf("count = %d\n", Test::cCount);//Test::cCount = 1000;//printf("count = %d\n", Test::cCount);return 0; }此代碼與上面的代碼的不同的是cCount變量變為public便于Test(作用域訪問)類調用,沒有任何的對象了,那么編譯運行,輸出結果應該是:
count = 0
說明這樣做,符合了我們的需求了。但是,不要高興的太早了,我們這樣真的可以么?加入我把代碼中的被注釋的那兩行加上(下面這兩行):
Test::cCount = 1000;printf("count = %d\n", Test::cCount);再次運行會發生什么呢?我們編譯運行,結果輸出為:
count = 0count = 1000那么多問題來了,客戶現在懵逼了,他會以為對象的個數有1000個,所以,這也是一個大的Bug啊,從本上講,這樣做也是無法滿足客戶的需求的,而且將cCount變為public,本身就是無法保證靜態成員變量的安全性,我們需要什么?
- 不依賴對象就可以訪問靜態成員變量
- 必須保證靜態成員變量的安全性
- 方便快捷得獲取靜態成員變量的值
那么靜態成員函數就要出馬了:
靜態成員函數的定義:
直接通過static關鍵字修飾成員函數即可
為了便于理解,我們先上一段代碼來理解一下靜態成員函數的性質:
#include <stdio.h>class Demo { private:int i; public:int getI();static void StaticFunc(const char* s);static void StaticSetI(Demo& d, int v); };int Demo::getI() {return i; }void Demo::StaticFunc(const char* s) {printf("StaticFunc: %s\n", s); }void Demo::StaticSetI(Demo& d, int v) {d.i = v; }int main() {Demo::StaticFunc("main Begin...");Demo d;d.StaticSetI(d, 20);printf("d.i = %d\n", d.getI());Demo::StaticSetI(d, 10);printf("d.i = %d\n", d.getI());Demo::StaticFunc("main End...");return 0; }以上代碼運行的結果為:
StaticFunc: main Begin... d.i = 20 d.i = 10 StaticFunc: main End...由代碼看到兩個靜態成員函數:
static void StaticFunc(const char* s); static void StaticSetI(Demo& d, int v);類調用靜態成員函數:
Demo::StaticFunc("main Begin...");對象調用靜態成員函數:
d.StaticSetI(d, 20);可以看出靜態成員函數的性質大體如下:
- 靜態成員函數是類中特殊的成員函數
- 靜態成員函數屬于整個類所有
- 可以通過類名(作用域訪問)直接訪問公有靜態成員函數
- 可以通過對象名訪問公有靜態成員函數
而且通過這段代碼:
void Demo::StaticSetI(Demo& d, int v) {d.i = v; }我么可以看出,靜態成員函數,沒有直接調用變量i,而是通過對象來間接調用變量i,這說明什么呢?說明:靜態成員函數不能訪問普通成員變量(函數),需通過對象間接訪問成員變量(函數)
下面做一個表格來對比一下靜態成員函數與普通成員函數的區別:
好了,理解了靜態成員函數,我們也應該來解決客戶的需求了吧:直接上代碼:
#include <stdio.h>class Test { private:static int cCount; public:Test(){cCount++;}~Test(){--cCount;}static int GetCount(){return cCount;} };int Test::cCount = 0;int main() {printf("count = %d\n", Test::GetCount());Test t1;Test t2;printf("count = %d\n", t1.GetCount());printf("count = %d\n", t2.GetCount());Test* pt = new Test();printf("count = %d\n", pt->GetCount());delete pt;printf("count = %d\n", Test::GetCount());return 0; }運行結果為:
count = 0 count = 2 count = 2 count = 3 count = 2分析: printf("count = %d\n", Test::GetCount());這段代碼運行之前,沒有創建對象,所以count = 0,
printf("count = %d\n", t1.GetCount()); printf("count = %d\n", t2.GetCount());這兩段代碼運行之前已經創建了t1,t2這兩個對象,所以都為:count = 2,
printf("count = %d\n", pt->GetCount());這個運行之前又在堆空間創建了一個對象,并且讓pt指針指向它,所以:count = 3
delete pt;printf("count = %d\n", Test::GetCount());在這兩行先將pt指向的對象刪除,所以最后是:count = 2
問題終于解決了!!!
總結:
- 靜態成員函數是類中的特殊的成員函數
- 靜態成員函數沒有隱藏的this指針
- 靜態成員函數可以通過類名直接訪問
- 靜態成員函數可以通過對象訪問
- 靜態成員函數只能直接訪問靜態成員變量(函數),而不能直接訪問普通成員變量(函數)
想獲得各種學習資源以及交流學習的加我:
qq:1126137994
微信:liu1126137994
可以共同交流關于嵌入式,操作系統,C++語言,C語言,數據結構等技術問題!
總結
以上是生活随笔為你收集整理的【C++深度剖析教程5】C++中类的静态成员函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab 从 excel读取 日期_
- 下一篇: centos安装思源黑体