Class で静的変数を使う

Object Class 内で静的変数を使います。

前田稔の超初心者のプログラム入門

プログラムの説明

  1. ゲームプログラムでは、画面上に飛び交う多数の弾丸を Object Class として管理することが良くあります。
    そのようなとき、Class 内で宣言されている全ての領域を毎回割り当てるのは無駄ですし、時には Class を通じて参照できる領域が必要なこともあります。
    そのような場合は Class 全体で共通に使用する領域を static で宣言します。
    以下のプログラムでは複数の class Cls を生成して、生成された全ての Cls から cnt の領域を共通に参照します。
    static 宣言を使ったシューティングゲームの例は 前田稔の超初心者のプログラム入門 から 「XNA/敵の多様な攻撃」などを参照して下さい。
    static int cnt; で宣言された領域は new Cls() で生成された全ての Object Class 内に一個だけ存在します。
  2. Cls Object Class の宣言と static 領域の宣言です。
    static int cnt; で静的変数を宣言しています。
    この領域は宣言しただけでは実体が無く、int Cls::cnt; で実体を割り当てます。
    int Cls::cnt = 10; のように、初期値を設定することも出来ます。
    初期値の指定が無いときは、グローバル領域と同様に規定値(ゼロ)でクリアされます。
    class Cls
    {
      public:
        static int  cnt;
        int         v1,v2;
        Cls(int V1, int V2);
        void disp();
    };
    //静的メンバ変数の実体となるグローバル変数
    int  Cls::cnt;
    
  3. static で宣言された領域は全ての class Cls から共通に参照されるので、最後に更新した唯一つの値が格納されています。
    次のプログラムの実行結果は、どうなるでしょう?。
    初期値を指定しないで cnt を定義して、コンストラクタで V1 の値を格納しています。
    /*★ class & static    前田 稔 ★*/
    #include <stdio.h>
    
    class Cls
    {
      public:
        static int  cnt;
        int         v1,v2;
        Cls(int V1, int V2);
        void disp();
    };
    //静的メンバ変数の実体となるグローバル変数
    int  Cls::cnt;
    
    //コンストラクタ
    Cls::Cls(int V1, int V2)
    {
        cnt = V1;
        v1 = V1;
        v2 = V2;
    }
    //メンバー関数
    void  Cls::disp()
    {
        printf("cnt=%d  v1=%d v2=%d\n", cnt,v1,v2);
    }
    
    int main()
    {
        Cls     *cls[5];
        int     i;
    
        for(i=0; i<5; i++)
        {   cls[i] = new Cls(i,i+10);
            cls[i]->disp();
        }
        for(i=0; i<5; i++)  delete cls[i];
        return 0;
    }
    
  4. それでは次のプログラムの実行結果は、どうなるでしょう?。
    初期値を 10 で cnt を定義して、コンストラクタでインクリメントしています。
    /*★ class & static    前田 稔 ★*/
    #include <stdio.h>
    
    class Cls
    {
      public:
        static int  cnt;
        int         v1,v2;
        Cls(int V1, int V2);
        void disp();
    };
    //静的メンバ変数の実体となるグローバル変数
    int  Cls::cnt = 10;
    
    //コンストラクタ
    Cls::Cls(int V1, int V2)
    {
        cnt++;
        v1 = V1;
        v2 = V2;
    }
    //メンバー関数
    void  Cls::disp()
    {
        printf("cnt=%d  v1=%d v2=%d\n", cnt,v1,v2);
    }
    
    int main()
    {
        Cls     *cls[5];
        int     i;
    
        for(i=0; i<5; i++)
        {   cls[i] = new Cls(i,i+10);
            cls[i]->disp();
        }
        for(i=0; i<5; i++)  delete cls[i];
        return 0;
    }
    
  5. 実行の結果です。
    new Cls(i,i+10); で5個の Cls クラスが生成されて呼び出されます。
    cnt の初期値は 10 ですが、クラスが呼び出される毎にコンストラクタでカウントアップされます。
    cnt は class Cls で共通なので、何番目のクラスでカウントアップしても反映されることに注目して下さい。
    cnt=11  v1=0 v2=10
    cnt=12  v1=1 v2=11
    cnt=13  v1=2 v2=12
    cnt=14  v1=3 v2=13
    cnt=15  v1=4 v2=14
    

超初心者のプログラム入門(C/C++)