【C++】静的メンバとは?クラス全体で共有する変数・関数 (static) の使い方

目次

はじめに

C++のクラスでは、通常、メンバ変数(データメンバ)はオブジェクトごとに個別の値を持ちます。Carクラスから car1car2 という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 は、widgetAwidgetB といった個々のオブジェクトに属するのではなく、Widget クラスという一つの大きな箱に属します。そのため、どのオブジェクトからアクセスしても、常に同じ一つの objectCount 変数を参照することになります。
  • コンストラクタ内の objectCount++: Widget オブジェクトが生成されるたびに、この共有されている objectCount がインクリメントされるため、生成されたオブジェクトの総数を正確にカウントできます。

2. 静的メンバ変数の定義 (int Widget::objectCount = 0;)

静的メンバ変数は、クラス定義の外(通常はソースファイル)で、スコープ解決演算子 :: を使って、その実体を定義し、初期化する必要があります。これはC++の特別なルールです。

3. 静的メンバ関数 (static void showCount())

  • 宣言: 関数の宣言の先頭に static を付けます。
  • 呼び出し: Widget::showCount(); のように、オブジェクトを生成していなくてもクラス名::関数名 という構文で直接呼び出すことができます。これは、静的メンバ関数がクラス全体に関連付けられているためです。
  • 制約: 静的メンバ関数の中では、静的ではない通常のメンバ(idなど)にアクセスすることはできません。なぜなら、静的メンバ関数は特定のオブジェクトに紐付いていないため、「どのオブジェクトの id なのか」を特定できないからです。

まとめ

今回は、C++の静的メンバについて解説しました。

  • 静的メンバ変数: クラス全体で共有される変数。オブジェクトの総数カウントなど、グローバルな状態管理に使う。
  • 静的メンバ関数: オブジェクトを生成しなくても呼び出せる関数。静的メンバ変数のみを操作する場合などに使う。

静的メンバは、個々のオブジェクトの状態とは独立した、「クラス」という概念そのものに関連するデータや機能を表現するための強力なツールです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次