回答:
以来は、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
m_
は、iのステータスを示すなどの接頭辞を追加できます。
static
残念ながら、C ++ではキーワードにはいくつかの無関係な意味があります
データメンバーに使用する場合、データはインスタンスではなくクラスに割り当てられます。
関数内のデータに使用する場合、データは静的に割り当てられ、ブロックが最初に入力されたときに初期化され、プログラムが終了するまで続きます。また、変数は関数内でのみ表示されます。ローカル静的のこの特別な機能は、シングルトンの遅延構築を実装するためによく使用されます。
コンパイルユニットレベル(モジュール)で使用すると、変数はグローバル(つまり、main
実行後に割り当てられ初期化され、main
終了後に破棄される)のようですが、変数は他のコンパイルユニットではアクセスまたは表示できません。
それぞれの用途で最も重要な部分を強調しました。エクスポートされていないクラス宣言も可能にする名前のない名前空間のために、使用(3)はやや推奨されません。
コードでは、static
キーワードは意味番号2で使用され、クラスやインスタンスとは関係ありません...これは関数の変数であり、コピーは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;
}
keyword static unfortunately has a few different unrelated meanings in C++
:)
関数内の静的変数
静的変数は関数の内部で作成され、スタックではなくプログラムの静的メモリに格納されます。
静的変数の初期化は、関数の最初の呼び出しで行われます。
静的変数は複数の関数呼び出しで値を保持します
静的変数の寿命はプログラムです
例
#include <iostream>
using namespace std;
class CVariableTesting
{
public:
void FuncWithStaticVariable();
void FuncWithAutoVariable();
};
void CVariableTesting::FuncWithStaticVariable()
{
static int staticVar = 0; //staticVar is initialised by 0 the first time
cout<<"Variable Value : "<<staticVar<<endl;
staticVar++;
}
void CVariableTesting::FuncWithAutoVariable()
{
int autoVar = 0;
cout<<"Variable Value : "<<autoVar<<endl;
autoVar++;
}
int main()
{
CVariableTesting objCVariableTesting;
cout<<"Static Variable";
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
objCVariableTesting.FuncWithStaticVariable();
cout<<endl;
cout<<"Auto Variable";
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
objCVariableTesting.FuncWithAutoVariable();
return 0;
}
出力:
静的変数
変数値:0
変数値:1
変数値:2
変数値:3
変数値:4
自動変数
変数値:0
変数値:0
変数値:0
変数値:0
変数値:0
簡単な答え:
静的変数は、それらがclass
(テンプレート化されていない)関数または(テンプレート化されていない)関数のメンバーであるかどうかに関係なく、技術的には、スコープがclass
または関数に制限されるグローバルラベルのように動作します。
MyClass& instance(){ static MyClass x("config.ini"); return x; }
、次のような非定数の初期化に非常に役立ちます。ローカルスタティックは、あなたが何を言っているにも関わらず、単にグローバルのようではないため、シングルスレッドで使用できる有効な移植可能な実装です。
static int i
インスタンスに固有のスコープを作成する方法を実際に実現する方法があるので、ego1.foo(); // i = 1
および$o2.foo(); // i = 1
...?