1. 問題引入
實作功能程式,統計某個類在程式執行期間生成對象的總數:
int global_cnt = ;
class cls
{
public:
int a;
cls();
~cls();
};
cls::cls()
{
++global_cnt;
}
cls::~cls()
{
--global_cnt;
}
int main(void)
{
std::cout << "目前cls對象個數: " << global_cnt << std::endl;
cls c1;
cls c2;
std::cout << "目前cls對象有個數: " << global_cnt << std::endl;
return ;
}
這是通過靜态全局變量來實作的,在構造函數中自加global_cnt變量,在析構函數自減global_cnt。global_cnt變量位于全局資料區,它不屬于具體某個對象。程式功能正确運作。
若不使用全局變量,還能怎麼辦?用類的靜态成員變量。
2. 靜态成員變量
回顧類的普通成員變量,具有的特點是:
(1) 外部可以通過對象名通路public成員變量;
(2) 成員變量是對象所專屬的;
(3) 成員變量不能在對象之間共享。
對于類的靜态成員變量來說,
(1) 它位于全局資料區,不依賴、也不屬于任何對象,而是歸屬于整個類所有;
(2) 通過類名、也可以通過對象名,通路公有的靜态成員變量;
(3) 所有對象共享靜态成員變量。
使用靜态成員變量也十分簡單,
(1) 在定義成員變量時直接通過static關鍵字修飾
class cls
{
public:
static int a; //靜态成員變量
}
(2) 注意,靜态成員變量需要在類的外部配置設定空間(定義)
采用靜态成員變量的程式為:
class cls
{
public:
int a;
static int cnt;
cls();
~cls();
int get_cnt()
{
return cnt;
}
};
int cls::cnt = ;
cls::cls()
{
++cnt;
}
cls::~cls()
{
--cnt;
}
int main(void)
{
std::cout << "目前cls對象個數為: " << c1.get_cnt() << std::endl;
cls c1;
cls c2;
std::cout << "目前cls對象個數為: " << c1.get_cnt() << std::endl;
return ;
}
3. 靜态成員函數
如上代碼,要得到cnt的值,就需要定以一個對象,通過對象去調用類的普通方法get_cnt()。假設我們想實作類似靜态成員變量的功能,在沒有定義類的前提下也可以擷取cnt數值,有什麼辦法?那就要用靜态成員函數了。
跟類的靜态成員變量類似,靜态成員函數:
(1) 歸屬于整個類所有;
(2) 既可以通過類名,也可以通過函數名通路靜态成員變量;
(3) 不含有this指針,具體原因在前面this指針文章有說到,http://blog.csdn.net/qq_29344757/article/details/76427588;
(4) 不能通路類中的普通成員變量和普通成員函數,即隻能通路類中的靜态成員變量和靜态成員函數。為什麼?
對于普通成員方法:
class cls
{
public:
static a;
void SetVal(int i)
{
a = i;
}
}
SetVal()方法的實作其實質是:
void SetVal(int i)
{
this->a = i;
}
所有類的對象都共享位于代碼段的成員函數,普通成員變量位于某個對象的堆棧空間,即普通成員變量在對象間不共享。方法通過this指針區分對象各自的堆棧的成員變量,靜态成員函數不含有this指針,無法區分,也就無法通路普通成員變量咯。
在定義成員函數時直接通過static關鍵字修飾:
class cls
{
public:
static int func();
static int func_t()
{
//...
}
}
int func()
{
//...
}
是以要實作沒有定義類的前提下也可以成員函數擷取cnt數值,隻需要将get_cnt()賦予靜态函數的屬性即可:
class cls
{
public:
int a;
static int cnt;
cls();
~cls();
static int get_cnt()
{
return cnt;
}
};
int cls::cnt = ;
cls::cls()
{
++cnt;
}
cls::~cls()
{
--cnt;
}
int main(void)
{
std::cout << "目前cls對象個數為: " << cls::get_cnt() << std::endl;
cls c1;
cls c2;
std::cout << "目前cls對象個數為: " << cls::get_cnt() << std::endl;
cls *c3 = new cls;
std::cout << "目前cls對象個數為: " << c1.get_cnt() << std::endl;
delete c3;
std::cout << "目前cls對象個數為: " << c1.get_cnt() << std::endl;
return ;
}
運作結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICdzFWRoRXdvN1LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9MGVONTUE5kerpWTmZEWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TM0cjNzETM4ETMzcDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)