c++ 靜態數據成員和靜態成員函數

 溫故而知新,閒來無事,再次捧了本c++primer 看了看,寫點c++靜態成員變量和成員函數吧,以前一直在用,但是有沒有完全搞懂什麼時候該用static 成員變量,什麼時候該用static function,什麼時候不要用靜態成員函數。

       靜態成員變量:primer中是這樣說的,對於所有的對象共有一個成員變量的就用static ,提供一個所有對象共有的一個成員變量比“每一個類對象維護一個成員變量” 要更有效。

       在這種情況下類的靜態數據成員提供了一個更好的方案靜態數據成員被當作該類類型的全局對象對於非靜態數據成員,每個類對象都有自己的拷貝而靜態數據成員對每個類類型只有一個拷貝靜態數據成員,只有一份由該類類型的所有對象共享訪問。同全局對象相比使用靜態數據成員有兩個優勢
      1 靜態數據成員沒有進入程序的全局名字空間因此不存在與程序中其他全局名字衝突的可能性
      2 可以實現信息隱藏靜態成員可以是private 成員而全局對象不能
      在類體中的數據成員聲明前面加上關鍵字static 就使該數據成員成爲靜態的static 數據成員,遵從public/private/protected 訪問規則,例如在下面定義的Account 類中_interestRate是被聲明爲double 型的私有靜態成員


class Account {
        Account( double amount, const string &owner );
        string owner() { return _owner; }

        static double getRate(){return _interestRate;}
private:
       static double _interestRate;
       double _amount;
       string _owner;
};



爲什麼把_interestRate 聲明爲static 而_amount 和_owner 不呢,這是因爲每個Account對應不同的主人有不同數目的錢而所有Account 的利率卻是相同的,因爲在整個程序中只有一個_interestRate 數據成員它被所有Account對象共享,所以把_interestRate聲明爲靜態成員,減少每個Account對象所需的存儲空間。

 

        靜態成員函數:靜態成員函數一般只能訪問靜態成員變量,如果要訪問非靜態成員變量的話,只能訪問某一個對象的非靜態成員變量和靜態成員函數。可以傳一個對象的指針,引用等參數給這個靜態成員函數。

      class   a   { 
public: 
    a():m_ia(123)   {} 
    int   getia()   {   return   m_ia;   } 
    static   int   f(a   &aa)   {   return   aa.getia();   } 
private: 
    int   m_ia; 
}; 

void   main() 

    a   aa; 
    cout<<a::f(aa); 
}  

 

     靜態成員函數中是不能調用非靜態成員的,包括非靜態成員函數和非靜態成員變量。那麼在非靜態成員函數中是否可以調用靜態成員函數呢?答案是肯定的,因爲靜態成員函數屬於類本身,在類的對象產生之前就已經存在了,所以在非靜態成員函數中是可以調用靜態成員函數的。其實,我們也可以以一個內存模型這個角度來考慮,也就是說,無論採取什麼樣的操作,程序代碼都是在內存中運行的,只有在內存中佔有了一席之地,我們才能訪問它。如果一個成員函數或成員變量還沒有在內存中產生,結果是無法訪問它的。所有靜態成員函數只能訪問靜態成員變量。

使用static關鍵字聲明的函數成員使靜態的,靜態成員函數同樣也屬於整個類,由同一個類的所有對象共同維護,爲這些對象所共享.  
      作爲成員函數,它的訪問屬性可以受到類的嚴格控制,對於公有的靜態函數成員函數,可以通過類名或對象名來調用,但一般情況下建議用對象名來引用靜態函數成員.注意,一般的成員函數只能通過對象名來調用.  
        由於一個類的靜態成員函數只有一個拷貝,因此它訪問對象的數據和函數時受到了限制.靜態成員函數可以直接訪問該類的靜態數據成員.而訪問非靜態數據成員, 必須通過參數傳遞方式得到對象名,然後通過對象名來訪問.可以看到,通過靜態函數成員訪問非靜態成員使相當麻煩的,一般的使用中,它主要用來訪問全局變量或同一個類中的靜態數據成員,特別是和後者一起使用,達到對同一個類中對象之間共享的數據進行維護的目的.  
        構造函數和析構函數不可以定義爲static,構造函數要給每一個對象一個this指針如果可以是靜態的,它如何構造和訪問this指針?
明顯是不可以的!

      靜態成員變量一般要在.cpp文件裏進行定義:double Account::_interestRate = 0.0589;靜態成員函數的聲明除了在類體中的函數聲明前加上關鍵字static 以及不能聲明爲const 或volatile 之外與非靜態成員函數相同,出現在類體外的函數定義不能指定關鍵字static.

       const string str = "liangxueliang";
    Account *Acc = new Account(222222,str);
    Acc->getRate();
    Account::getRate();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章