1. 程式人生 > 實用技巧 >18 類的靜態成員函式

18 類的靜態成員函式

目錄

1 未完成的需求

  • 統計在程式執行期間某個類的物件數目

  • 保證程式的安全性(不能使用全域性變數)

  • 隨時可以獲取當前物件的數目(Failure)=> 必須借用一個物件才能呼叫“獲取當前物件的數目”的函式

  • 示例:解決方案的嘗試

    • Demo

      #include <stdio.h>
      
      class Test
      {
      public:
          static int cCount;
      public:
          Test()
          {
              cCount++;
          }
          ~Test()
          {
              --cCount;
          }
          int getCount()
          {
              return cCount;
          }
      };
      
      int Test::cCount = 0;
      
      int main()
      {
          printf("count = %d\n", Test::cCount);
          
          Test::cCount = 1000;  //誤賦值
          
          printf("count = %d\n", Test::cCount);
          
          return 0;
      }
      
    • 編譯

      count = 0
      count = 1000
      

2 分析

  • 需要什麼?
    • 不依賴物件就可以訪問靜態成員變數
    • 必須保證靜態成員變數的安全性
    • 方便快捷地獲取靜態成員變數的值

3 靜態成員函式

  • 在 C++ 中可以定義靜態成員函式

    • 靜態成員函式是類中特殊的成員函式
    • 靜態成員函式屬於整個類所有
    • 可以通過類名直接訪問公有靜態成員函式
    • 可以通過物件名訪問公有靜態成員函式
  • 靜態成員函式的定義

    • 直接通過 static 關鍵字修飾成員函式
    class Test
    {
    public:
        static void func1(){}
        static int fcun2();
    };
    
    int Test::func2(){
        return 0;
    }
    
  • 示例:靜態成員函式使用

    • Demo

      #include <stdio.h>
      
      class Demo
      {
      private:
          int i;
      public:
          int getI();
          static void StaticFunc(const char* s);  //靜態成員函式
          static void StaticSetI(Demo& d, int v);  //靜態成員函式
      };
      
      int Demo::getI()
      {
          return i;
      }
      
      void Demo::StaticFunc(const char* s)
      {
          printf("StaticFunc: %s\n", s);
      }
      
      void Demo::StaticSetI(Demo& d, int v)
      {
          d.i = v;
      }
      
      int main()
      {
          Demo::StaticFunc("main Begin...");
          
          Demo d;
          
          Demo::StaticSetI(d, 10);
          
          printf("d.i = %d\n", d.getI());
          
          Demo::StaticFunc("main End...");
          
          return 0;
      }
      
    • 編譯執行

      main Begin...
      d.i = 10
      main End...
      
  • 靜態成員函式 VS 普通成員函式

    靜態成員函式 普通成員函式
    所有物件共享 Yes Yes
    隱含 this 指標 No Yes
    訪問普通成員變數(函式) No Yes
    訪問靜態成員變數(函式) Yes Yes
    通過類名直接呼叫 Yes No
    通過物件名直接呼叫 Yes Yes
  • 示例:解決方案

    • Demo

      #include <stdio.h>
      
      class Test
      {
      private:
          static int cCount;
      public:
          Test()
          {
              cCount++;
          }
          ~Test()
          {
              --cCount;
          }
          static int GetCount()
          {
              return cCount;
          }
      };
      
      int Test::cCount = 0;
      
      int main()
      {
          printf("count = %d\n", Test::GetCount());
          
          Test t1;
          Test t2;
          
          printf("count = %d\n", t1.GetCount());
          printf("count = %d\n", t2.GetCount());
          
          Test* pt = new Test();
          
          printf("count = %d\n", pt->GetCount());
          
          delete pt;
          
          printf("count = %d\n", Test::GetCount());
          
          return 0;
      }
      
    • 編譯執行

      count = 0
      count = 2
      count = 2
      count = 3
      count = 2