web-dev-qa-db-ja.com

メンバー関数の静的変数

誰かがメンバー関数の静的変数がC++でどのように機能するか説明してください。

次のクラスを考えます:

class A {
   void foo() {
      static int i;
      i++;
   }
}

Aの複数のインスタンスを宣言した場合、1つのインスタンスでfoo()を呼び出すと、すべてのインスタンスで静的変数iが増加しますか?または、それが呼び出されたものだけですか?

各インスタンスにはiの独自のコピーがあると想定しましたが、別の方法で示したいくつかのコードをステップスルーするようです。

145
monofonik

class Aは非テンプレートクラスであり、A::foo()は非テンプレート関数です。プログラム内にはstatic int iのコピーが1つしかありません。

Aオブジェクトのインスタンスは、同じiに影響し、iの存続期間はプログラム全体を通して残ります。例を追加するには:

A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 2
o3.foo(); // i = 3
o1.foo(); // i = 4
152
iammilind

キーワードstaticは、残念ながらC++ではいくつかの異なる無関係な意味を持っています

  1. データメンバに使用する場合、データはインスタンスではなくクラスに割り当てられます。

  2. 関数内のデータに使用する場合、データが静的に割り当てられることを意味し、ブロックに初めて入ったときに初期化され、プログラムが終了するまで続きます。また、変数は関数内でのみ表示されます。ローカルスタティックのこの特別な機能は、シングルトンの遅延構築を実装するためによく使用されます。

  3. コンパイル単位レベル(モジュール)で使用される場合、変数はグローバル(つまり、mainが実行される前に割り当てられ初期化され、mainが終了した後に破棄される)が、それは変数は他のコンパイル単位ではアクセスまたは表示されません

使用するたびに最も重要な部分を強調しました。使用(3)は、エクスポートされていないクラス宣言も許可する名前のない名前空間を支持してやや推奨されません。

コードでは、staticキーワードは意味番号2で使用され、クラスやインスタンスとは関係ありません...これはfunctionの変数であり、コピーは1つだけにしてください。

正確にiammilindは、関数がテンプレート関数である場合、その変数の複数のインスタンスが存在する可能性があると述べました(その場合、関数自体は実際に多くの異なるコピーに存在する可能性があるためプログラム)。その場合でも、クラスとインスタンスは無関係です...次の例を参照してください。

#include <stdio.h>

template<int num>
void bar()
{
    static int baz;
    printf("bar<%i>::baz = %i\n", num, baz++);
}

int main()
{
    bar<1>(); // Output will be 0
    bar<2>(); // Output will be 0
    bar<3>(); // Output will be 0
    bar<1>(); // Output will be 1
    bar<2>(); // Output will be 1
    bar<3>(); // Output will be 1
    bar<1>(); // Output will be 2
    bar<2>(); // Output will be 2
    bar<3>(); // Output will be 2
    return 0;
}
128
6502