C++の5つのストレージクラスの役割を解析する

4264 ワード

ストレージ・クラスは、C++プログラムの変数/関数の範囲(可視性)とライフサイクルを定義します.これらの説明子は、修飾されたタイプの前に配置されます.以下に、C++プログラムで使用可能なストレージ・クラスを示します.
  • auto
  • register
  • static
  • extern
  • mutable

  • ストレージクラス説明子は、自動ストレージクラス(autmatic storage class)と静的ストレージクラス(static storage class)の2つのストレージクラスに分けることができます.キーワードautoおよびregtsterは、クラス変数の自動格納を宣言するために使用されます.この変数は宣言されたブロックに入ると生成され、ブロックアクティビティ中に存在し、このブロックを終了すると削除されます.
    変数のみが自動ストレージクラスとして使用できます.関数のローカル変数とパラメータは、通常、自動ストレージクラスです.ストレージクラス説明子autoは、変数が自動ストレージクラスであることを明示的に宣言します.たとえば、float変数xおよびyが自動格納クラスのローカル変数であることを示す宣言は、変数を定義する関数体にのみ存在します.
    
    auto float x,y;
    

    ローカル変数はデフォルトで自動格納クラスなので、キーワードautoはあまり使用されません.register宣言は通常不要です.現在の最適化コンパイラは、通常、よく使用される変数を識別し、プログラマによるregister宣言を必要とせずにレジスタに教えることを決定します.キーワードexternおよびstaticは、静的ストレージクラス変数および関数を宣言する識別子です.この変数はプログラムの実行開始時から存在します.変数の場合、プログラムが実行を開始すると、ストレージスペースが割り当てられ、初期化されます.関数の場合、プログラムの実行開始時から関数名が存在します.ただし、変数と関数名はプログラムの実行開始時から存在するが、これらの識別子がプログラム全体で使用できるわけではない.静的ストレージ・クラスには、グローバル変数や関数名などの外部識別子と、ストレージ・クラス・ディスクリプタStaticで宣言されたローカル変数の2つの識別子があります.グローバル変数と関数名のデフォルトは、ストレージクラスの説明子externです.グローバル変数の生成時に変数宣言を任意の関数定義の外に配置し、プログラムの実行中にグローバル変数の値を保存します.グローバル変数および関数は、ファイルで宣言または定義されている任意の関数で参照できます.
    具体的には、autoストレージクラスについて説明します.
    Autoストレージクラスは、すべてのローカル変数のデフォルトのストレージクラスです.
    
    {
      int mount;
      auto int month;
    }
    

    上記の例では、同じストレージクラスを持つ2つの変数が定義されています.autoは関数内でのみ使用できます.すなわち、autoはローカル変数のみを修飾できます.
    registerストレージクラス
    registerストレージクラスは、RAMに格納されるローカル変数ではなくレジスタに格納されるローカル変数を定義するために使用される.これは、変数の最大サイズがレジスタのサイズ(通常は単語)に等しく、メモリ位置がないため、1元の'&'演算子を適用できないことを意味します.
    
    {
      register int miles;
    }
    

    レジスタは、カウンタなどの高速アクセスが必要な変数にのみ使用されます.また、'register'を定義することは、変数がレジスタに格納されることを意味するものではありません.これは、ハードウェアおよび実装の制限に応じて、変数がレジスタに格納される可能性があることを意味します.staticストレージクラス
    staticストレージクラスは、コンパイラがプログラムのライフサイクル中にローカル変数の存在を維持し、役割ドメインに入るたびに作成および破棄する必要がないことを示します.したがって、static修飾ローカル変数を使用すると、関数呼び出し間でローカル変数の値を維持できます.static修飾子は、グローバル変数にも適用できます.staticがグローバル変数を修飾すると、変数の役割ドメインが宣言されたファイルに制限されます.C++では、staticがクラスデータメンバーに使用されると、そのメンバーのコピーがクラスのすべてのオブジェクトで共有されるのは1つだけです.
    
    #include 
    
    //      
    void func(void);
    
    static int count = 10; /*      */
    
    main()
    {
      while(count--)
      {
        func();
      }
      return 0;
    }
    //     
    void func( void )
    {
      static int i = 5; //       
      i++;
      std::cout << "i is " << i ;
      std::cout << " and count is " << count << std::endl;
    }
    
    

    上記のコードがコンパイルおよび実行されると、次の結果が得られます.
    
    i is 6 and count is 9
    i is 7 and count is 8
    i is 8 and count is 7
    i is 9 and count is 6
    i is 10 and count is 5
    i is 11 and count is 4
    i is 12 and count is 3
    i is 13 and count is 2
    i is 14 and count is 1
    i is 15 and count is 0
    

    externストレージクラス
    externストレージクラスは、グローバル変数の参照を提供するために使用され、グローバル変数はすべてのプログラムファイルに表示されます.「extern」を使用すると、初期化できない変数に対して、以前に定義した格納場所に変数名が割り当てられます.複数のファイルがあり、他のファイルで使用できるグローバル変数または関数が定義されている場合は、他のファイルでexternを使用して定義された変数または関数の参照を得ることができます.externは、別のファイルでグローバル変数または関数を宣言するために使用されることが理解されます.extern修飾子は、通常、同じグローバル変数または関数を共有する2つ以上のファイルがある場合に、以下に示すように、最初のファイル:main.cpp
    
    #include 
    
    int count ;
    extern void write_extern();
    
    main()
    {
      count = 5;
      write_extern();
    }
    
    

    2番目のファイル:support.cpp
    
    #include 
    
    extern int count;
    
    void write_extern(void)
    {
      std::cout << "Count is " << count << std::endl;
    }
    
    

    ここで、2番目のファイルのexternキーワードは、1番目のファイルmainに既に存在することを宣言するために使用される.cppで定義されたcount.次に、この2つのファイルをコンパイルします.
    
    $g++ main.cpp support.cpp -o write
    

    これによりwrite実行可能プログラムが生成され、writeを実行しようとします.次の結果が得られます.
    
    $./write
    5
    

    mutableストレージクラス
    mutable説明子はクラスのオブジェクトにのみ適用されます.このチュートリアルの最後に説明します.オブジェクトのメンバーが定数に代わることができます.すなわち、mutableメンバーはconstメンバー関数で変更できます.