1. 程式人生 > >c++ 靜態資料成員和靜態成員函式

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();