靜态資料成員
用static修飾類中的資料成員,被稱為靜态資料成員。他并不依賴于對象的執行個體化,而依賴于類。是以靜态資料成員不在構造函數中初始化,它單獨進行初始化;就算對象沒有執行個體化,他也存在。而普通資料成員依賴于對象的執行個體化,若對象沒有執行個體化,它就不存在。
假設有一個Tank類
class Tank
{
public:
Tank(char code);
~Tank();
void fire();
static int getCount();//靜态成員函數
private:
static int s_iCount;//靜态資料成員,該函數用來記錄坦克個數
char m_cCode;//坦克的名稱
};
若對象還沒有執行個體化,可以用 類名::靜态資料成員名稱 來通路
Tank::s_iCount;
普通資料成員和靜态資料成員的差別:
執行個體化tank之後,s_iCount的值會變化,但是他在記憶體中的個數仍然為1個,而m_strCode會有很多個(根據執行個體化了幾個對象)
是以,靜态資料成員隻有一份
靜态成員函數
理論:靜态成員函數不能調用非靜态成員函數和非靜态資料成員,但是可以調用靜态資料成員
原理:
還是前面的代碼
static int getCount()
{
m_strCode = '01''//錯誤
}
因為靜态成員函數同樣也不依賴于對象,是以在這個靜态成員函數的參數中無this指針,那麼在調用非靜态資料成員m_strCode的時候,編譯器無法知道調用哪一個對象的資料成員,則會編譯出錯。
而靜态成員函數可以調用靜态資料成員是因為靜态資料成員在記憶體中就一個,不需要區分。
注:static成員函數不可以用const修飾,因為用const修飾的成員函數,實質上是const修飾的成員函數參數中隐藏的this指針,而static成員函數無this指針。
總結:
- 靜态資料成員必須單獨初始化
- 靜态成員函數不能調用非靜态成員函數和非靜态資料成員
- 靜态資料成員隻有一份,且不依賴對象而存在
代碼示例
#include<iostream>
using namespace std;
class Tank
{
public:
Tank(char code);
~Tank();
void fire();
static int getCount();//靜态成員函數
private:
static int s_iCount;//靜态資料成員
char m_cCode;
};
int Tank::s_iCount = 10;//對靜态資料成員初始化,在構造函數的外面進行
Tank::Tank(char code)
{
m_cCode = code;
s_iCount++;
cout<<"Tank"<<endl;
}
Tank::~Tank()
{
s_iCount--;
cout<<"~Tank"<<endl;
}
void Tank::fire()
{
cout<<"Tank--fire"<<endl;
}
int Tank::getCount()//在類外定義的時候,不需要在前面加static
{
return s_iCount;
}
int main()
{
cout<<Tank::getCount()<<endl;
Tank *p = new Tank('A');
cout<<Tank::getCount()<<endl;
Tank *q = new Tank('B');
cout<<q->getCount()<<endl;
delete p;
p = NULL;
delete q;
q = NULL;
cout<<Tank::getCount()<<endl;
return 0;
}
運作結果: