C++でシングルトンクラス
この記事は最終更新日から1年以上が経過しています。
芽萌丸プログラミング部@programming
投稿日 2021/2/17
更新日 2021/2/17 ✏

C++でシングルトンクラス

C++で標準ライブラリ以外は一切使わずに簡単なシングルトンクラスを作る方法です。

目次:

前提

  • Ubuntu 16.04 LTS
  • g++ 7.5.0
  • C++11

サンプルコード

シングルトンクラス Singleton のサンプルコードです。

Singleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

using namespace std;
/**
 * シングルトンのサンプルクラス
 */
class Singleton {
private:
  /**
   * コンストラクタ
   *
   * NOTE:
   * インスタンス新規作成には必ずgetInstance()を使わせるために
   * コンストラクタをプライベート化して隠蔽。
   */
  Singleton() {
    cout << "Singleton instance created!" << endl;
  }
  /** インスタンスのポインタ */
  static Singleton* instance;
  /** 何らかのテキトーなデータ */
  int data = 123;
public:
  /**
   * インスタンス取得メソッド
   * @return シングルトンインスタンス
   */
  static Singleton* getInstance() {
    // 生成済みのインスタンスがなければ新規作成:
    if (instance == NULL) instance = new Singleton();
    return instance;
  }
  /**
   * dataの値をゲットするだけのテキトーなメソッド
   */
  int getData() {
    return Singleton::getInstance()->data;
  }
  /**
   * dataの値をセットするだけのテキトーなメソッド
   */
  void setData(int data) {
    Singleton::getInstance()->data = data;
  }
};
// インスタンスのポインタを初期化:
Singleton* Singleton::instance = 0;

#endif

コードレビュー:

  • コンストラクタはprivateの中に隠蔽し、newの代わりにSingleton::getInstance()でインスタンスを取得させます。
  • static Singleton* instance;で自身のインスタンス(のポインタ)を保持しています。
  • クラスの外でSingleton* Singleton::instance = 0;で自身のインスタンス(のポインタ)を初期化しています。

上記の Singleton クラスの使い方は以下の通り:

Singleton-test.cpp

#include<iostream>
#include "Singleton.h"

using namespace std;

int main(int argc, char* argv[]) {

  // インスタンス1を生成:
  Singleton* inst1 = Singleton::getInstance();
  cout << "インスタンス1のアドレス: " << inst1 << endl;
  // インスタンス2を生成:
  Singleton* inst2 = Singleton::getInstance();
  cout << "インスタンス2のアドレス: " << inst2 << endl;
  // NOTE: シングルトンなのでインスタンス1と2のアドレスは同じはず。

  // 各インスタンスのメソッドを呼び出してみる:
  cout << "インスタンス1のdata: " << inst1->getData() << endl;
  cout << "インスタンス2のdata: " << inst2->getData() << endl;

  // インスタンス1の保持データを更新:
  cout << "インスタンス1のdataを999に更新:" << endl;
  inst1->setData(999);

  // もう一度各インスタンスのメソッドを呼び出してみる:
  cout << "インスタンス1のdata: " << inst1->getData() << endl;
  cout << "インスタンス2のdata: " << inst2->getData() << endl;

  // インスタンス3を生成:
  Singleton* inst3 = Singleton::getInstance();
  cout << "インスタンス3のアドレス: " << inst3 << endl;
  cout << "インスタンス3のdata: " << inst3->getData() << endl;

  return 0;
}

コンパイル&実行:

## コンパイル&実行:
$ g++ -o a.out Singleton-test.cpp && ./a.out 

Singleton instance created!
インスタンス1のアドレス: 0x204dc20
インスタンス2のアドレス: 0x204dc20
インスタンス1のdata: 123
インスタンス2のdata: 123
インスタンス1のdataを999に更新:
インスタンス1のdata: 999
インスタンス2のdata: 999
インスタンス3のアドレス: 0x204dc20
インスタンス3のdata: 999

実行結果の通りgetInstance()で取得したインスタンスは常に同じアドレス(同じインスタンス)を見ていることがわかります。

以上です。

関連


芽萌丸プログラミング部
芽萌丸プログラミング部@programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。