staticキーワードは以下の4つの異なる目的で使用されます:
staticなローカル変数は、関数を抜けてもずっと値を保持し続けます。例えば以下のコードの場合には、関数内のstatic変数を使用して、その関数が今までに何回呼ばれたかどうかというのを追跡しています:
void foo() { static int counter = 0; cout << "foo関数は " << ++counter << " 回呼ばれました\n"; } int main() { for( int i = 0; i < 10; ++i ) foo(); }
クラスのデータメンバーとして使用すると、すべてのクラスのインスタンス間で共有される変数として使用できます。
class Foo { public: Foo() { ++numFoos; cout << "私たちはFooクラスのインスタンスを " << numFoos << " 個作りました\n"; } private: static int numFoos; }; int Foo::numFoos = 0; // numFoosのメモリを割り当てて初期化します int main() { Foo f1; Foo f2; Foo f3; }
上記の例の場合には、staticクラス変数のnumFoosを、3つのFooクラスのインスタンス(f1, f2, f3)間で共有しています。numFoosはFooクラスがいままでに何個インスタンス化されたのか、という数をカウントします。
クラスの関数のメンバーに対して使用すると、関数は暗示的なthisパラメータを受け取らなくなり、クラスに属さない関数と同じように振る舞います。これはstaticなクラス関数は、クラスのインスタンスを作成しなくても呼ぶことができるという意味です。
class Foo { public: Foo() { ++numFoos; cout << "私たちはFooクラスのインスタンスを " << numFoos << " 個作りました\n"; } static int getNumFoos() { return numFoos; } private: static int numFoos; }; int Foo::numFoos = 0; // numFoosのメモリを割り当てて初期化します int main() { Foo f1; Foo f2; Foo f3; cout << "これまでに " << Foo::getNumFoos() << " 個のFooクラスのインスタンスが作成されています\n"; }