目次
はじめに
C++のクラスでは、通常、メンバ変数(データメンバ)はオブジェクトごとに個別の値を持ちます。Car
クラスから car1
と car2
という2つのオブジェクトを作れば、それぞれの gas
(ガソリン量)は別々に管理されます。
しかし、「このクラスから、合計でいくつのオブジェクトが作られたか」といった、クラス全体で共有したい情報を管理したい場合があります。このような場面で使うのが「静的メンバ」です。
この記事では、クラス全体で一つの値を共有する静的メンバ変数と、オブジェクトを生成しなくても呼び出せる静的メンバ関数について、その仕組みと使い方を解説します。
静的メンバを使ったサンプルコード
このコードは、Widget
(ガジェット)クラスを定義し、静的メンバ変数 objectCount
を使って、これまでに生成された Widget
オブジェクトの総数をカウントします。
完成コード
#include <iostream>
using namespace std;
class Widget {
private:
int id;
public:
// 1. 静的メンバ変数の「宣言」
static int objectCount;
// コンストラクタ
Widget() {
// オブジェクトが作られるたびに、共有カウンタを1増やす
objectCount++;
id = objectCount; // IDとして連番を割り当てる
cout << "Widgetオブジェクトが作成されました。(ID: " << id << ")" << endl;
}
// 3. 静的メンバ関数の「宣言」と「実装」
static void showCount() {
cout << "現在、Widgetオブジェクトは合計 " << objectCount << " 個あります。" << endl;
}
};
// 2. 静的メンバ変数の「定義」と「初期化」
// 必ずクラスの外に記述する
int Widget::objectCount = 0;
int main() {
// オブジェクトが一つもない状態でも、静的メンバ関数は呼び出せる
Widget::showCount();
cout << "\n--- Widget A を作成 ---" << endl;
Widget widgetA;
Widget::showCount();
cout << "\n--- Widget B を作成 ---" << endl;
Widget widgetB;
Widget::showCount();
return 0;
}
実行結果
現在、Widgetオブジェクトは合計 0 個あります。
--- Widget A を作成 ---
Widgetオブジェクトが作成されました。(ID: 1)
現在、Widgetオブジェクトは合計 1 個あります。
--- Widget B を作成 ---
Widgetオブジェクトが作成されました。(ID: 2)
現在、Widgetオブジェクトは合計 2 個あります。
コードの解説
1. 静的メンバ変数 (static int objectCount;
)
- 宣言: クラス定義の中で、変数の宣言の先頭に
static
を付けます。 - 性質:
objectCount
は、widgetA
やwidgetB
といった個々のオブジェクトに属するのではなく、Widget
クラスという一つの大きな箱に属します。そのため、どのオブジェクトからアクセスしても、常に同じ一つのobjectCount
変数を参照することになります。 - コンストラクタ内の
objectCount++
:Widget
オブジェクトが生成されるたびに、この共有されているobjectCount
がインクリメントされるため、生成されたオブジェクトの総数を正確にカウントできます。
2. 静的メンバ変数の定義 (int Widget::objectCount = 0;
)
静的メンバ変数は、クラス定義の外(通常はソースファイル)で、スコープ解決演算子 ::
を使って、その実体を定義し、初期化する必要があります。これはC++の特別なルールです。
3. 静的メンバ関数 (static void showCount()
)
- 宣言: 関数の宣言の先頭に
static
を付けます。 - 呼び出し:
Widget::showCount();
のように、オブジェクトを生成していなくても、クラス名::関数名
という構文で直接呼び出すことができます。これは、静的メンバ関数がクラス全体に関連付けられているためです。 - 制約: 静的メンバ関数の中では、静的ではない通常のメンバ(
id
など)にアクセスすることはできません。なぜなら、静的メンバ関数は特定のオブジェクトに紐付いていないため、「どのオブジェクトのid
なのか」を特定できないからです。
まとめ
今回は、C++の静的メンバについて解説しました。
- 静的メンバ変数: クラス全体で共有される変数。オブジェクトの総数カウントなど、グローバルな状態管理に使う。
- 静的メンバ関数: オブジェクトを生成しなくても呼び出せる関数。静的メンバ変数のみを操作する場合などに使う。
静的メンバは、個々のオブジェクトの状態とは独立した、「クラス」という概念そのものに関連するデータや機能を表現するための強力なツールです。