静的 (C++)
static キーワードは、変数、関数、クラス データ メンバー、およびクラス関数を宣言するために使用できます。
既定では、すべてのブロックの外部で定義された変数またはオブジェクトには外部リンケージが含まれ、存続期間は静的です。 静的存続期間は、オブジェクトまたは変数がプログラム起動時に割り当てられ、プログラムの終了時に解放されることを意味します。 外部リンケージは、変数が宣言されたファイルの外部から変数名が参照できることを意味します。 逆に、内部リンケージは、変数が宣言されたファイルの外部でその名前を参照できないことを意味します。
キーワード static は次の状況で使用できます。
ファイル スコープ (グローバル スコープまたは名前空間スコープ、あるいはその両方) で変数または関数を宣言する場合、static キーワードは、変数または関数に内部リンケージがあることを指定します。 変数を宣言すると、変数は静的存続期間が設定され、コンパイラによって 0 に初期化されます (別の値を指定していない場合)。
関数で変数を宣言する場合、static キーワードは、その関数の呼び出しと呼び出しの間に変数がその状態を保持することを指定します。
クラス宣言でデータ メンバーを宣言する場合、static キーワードは、メンバーの 1 つのコピーがクラスのすべてのインスタンスで共有されることを指定します。 静的データ メンバーはファイル スコープで定義する必要があります。 const static として宣言した整数データ メンバーには、初期化子を定義できます。
クラス宣言でメンバー関数を宣言する場合、static キーワードは、関数がクラスのすべてのインスタンスで共有されることを指定します。 静的メンバー関数は、関数に暗黙の this ポインターがないため、インスタンス メンバーにアクセスできません。 インスタンス メンバーにアクセスするには、インスタンスのポインターまたは参照であるパラメーターを受け取る関数を宣言します。
共用体のメンバーを static として宣言することはできません。 ただし、グローバルに宣言された匿名共用体は、明示的に static として宣言する必要があります。
詳細については、「auto」、「extern」、および「register」を参照してください。
使用例
次の例では、関数内で static として宣言された変数が、その関数の呼び出しと呼び出しの間、どのようにその状態を保持するかを示します。
// static1.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
void showstat( int curr ) {
static int nStatic; // Value of nStatic is retained
// between each function call
nStatic += curr;
cout << "nStatic is " << nStatic << endl;
}
int main() {
for ( int i = 0; i < 5; i++ )
showstat( i );
}
クラスでの static の使用例を次に示します。
// static2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class CMyClass {
public:
static int m_i;
};
int CMyClass::m_i = 0;
CMyClass myObject1;
CMyClass myObject2;
int main() {
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
myObject1.m_i = 1;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
myObject2.m_i = 2;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
CMyClass::m_i = 3;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
}
次の例では、メンバー関数内で static として宣言されたローカル変数を示します。 静的変数は、プログラム全体で使用できます。型のすべてのインスタンスは、静的変数の同じコピーを共有します。
注意
マルチスレッド アプリケーションの静的ローカル変数に値を割り当てる操作はスレッド セーフではないため、プログラミングではお勧めしません。
// static3.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
struct C {
void Test(int value) {
static int var = 0;
if (var == value)
cout << "var == value" << endl;
else
cout << "var != value" << endl;
var = value;
}
};
int main() {
C c1;
C c2;
c1.Test(100);
c2.Test(100);
}