C++中的靜態成員和靜態函數


1 靜態成員變量

1.1 定義靜態成員變量

  • 關鍵字static可以用於說明一個類的成員

  • 靜態成員提供了一個同類對象的共享機制

  • 把一個類的成員說明static時,無論這個類有多少對象被創建,這些對象共享這個static成員

  • 靜態成員局部於類,他不是對象的成員

    如同下圖所示,對於同類定義出來的對象A,B,C,D其中成員變量是ch是每個對象自己特有,但是靜態成員變量s是全體對象共用,只要有一個對象修改了這個s的值,則全部相同類定義的對象中的s都發生改變。
    圖片名稱

圖片名稱

如同上圖所示,對於同類定義出來的對象A,B,C,D其中成員變量是ch是每個對象自己特有,但是靜態成員變量s是全體對象共用,只要有一個對象修改了這個s的值,則全部相同類定義的對象中的s都發生改變。

#include<iostream.h>
class  counter
{
    public :
      counter (int a) 
      { 
          mem = a; 
      }
      int mem;				//公有數據成員
      static  int  Smem ;	//公有靜態數據成員
} ;
![image](uploading...)
int  counter :: Smem = 1;	//初始值為1 
void main()
{   counter c(5);
    int i ;
    for( i = 0 ; i < 5 ; i ++ )
      { counter::Smem += i ;
         cout << counter::Smem << '\t' ;  //訪問靜態成員變量方法2
      }
    cout<<endl; cout<<"c.smem="<<c.Smem<<endl; 	  //訪問靜態成員變量方法1
    cout<<" c.mem="<<c.mem<<endl;
}

1.2 靜態成員函數

  • 靜態成員變量冠以關鍵詞static
  • 靜態成員變量是不依賴類數據結構的共同操作
  • 在類外調用靜態成員變量是有 類名::作為限定詞,或者通過對象進行調用

舉個例子

class X
{
    public:
    	static void printfID()
        {
            // count<<id<<endl; 錯誤做法
            count<<s_id<<endl;  //正確做法
        }
    private:
    int id;
    static int s_id;
}
//使用static 修飾的變量是屬於整個類,所有的對象都可以共用


其中 // count<<id<<endl;是錯誤,原因如下圖所示:

圖片名稱

對於每一個對象都存在一個獨有的id變量,但是對於static 修飾的函數是共用,如果使用static函數通用普通的的成員變量就無法區分是哪一個對象的id變量。

1.3使用static的好處(參考)

  1. 第一個好處肯定就是占用內存小,不需要對每一個對象都分配函數空間。

  2. 可以實現某些特殊的設計模式:如Singleton

  3. 可以封裝某些算法,比如數學函數,如ln,sin,tan等等,這些函數本就沒必要屬於任何一個對象,所以從類上調用感覺更好,比如定義一個數學函數類Math,調用Math::sin(3.14);如果非要用非靜態函數,那就必須:Math math; math.sin(3.14);行是行,只是不爽:就為了一個根本無狀態存儲可言的數學函數還要引入一次對象的構造和一次對象的析構,當然不爽。而且既然有了對象,說不得你還得小心翼翼的定義拷貝構造函數、拷貝賦值運算符等等,對於一些純算法的東西顯然是不合適的。

  4. 由於沒有this指針,可以把某些系統API的回調函數以靜態函數的形式封裝到類的內部。因為系統API的回調函數通常都是那種非成員函數(孤立函 數),沒有this指針的。比如你可以在類的內部寫一個線程函數供CreateThread創建線程用,如果沒有靜態函數,那么這種回調函數就必須定義成 全局函數(非靜態成員函數指針無法轉換成全局函數指針),從而影響了OO的“封裝性”。

  5. 總之,從OOA/OOD的角度考慮,一切不需要實例化就可以有確定行為方式的函數都應該設計成靜態的。

    ​ 以上只是一些基本的考慮,並不是絕對的。絕對東西的只有一點:“靜態函數不需要實例化就可以被調用,不會也不可以調用或操縱非靜態成員”。記住這一點,那么實際編程中何時需要用,何時適合用,自然就更容易作出決定了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM