天天看點

c++類的靜态成員變量/靜态成員函數

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 ;
}
           

運作結果:

c++類的靜态成員變量/靜态成員函數

繼續閱讀