デザインパターンの本 を立ち読みしていて、そのうちプログラム内で一意の番号を振ることもあるだろうと思い、シングルトンパターンでID生成クラスを実装してみた。仕様は以下の通り。
- 最初のIDは1
- 一度IDを取得すると1増える
- 現在のIDを確認できる
- 次のIDを確認できる
- プログラム内で一意
C++でシングルトンパターンを実装する方法はここやここを参考にした。
要するに、ConstructorをPrivateにして、getInstanceメンバでstaticなインスタンスを取得する、ということらしい。ただし、static変数を使っているので、スレッドセーフとはならず、マルチスレッド環境で使用するにはもうちょっと改良する必要がありそうだ。
ソースは以下の通り。
- idgenerator.hpp
#ifndef __IDGENERATOR_HPP__ #define __IDGENERATOR_HPP__ namespace DECS { namespace{ const unsigned int DEFAULT_ORIGIN = 0; const unsigned int DEFAULT_INTERVAL = 1; } class IDGenerator { private: IDGenerator() : current_(DEFAULT_ORIGIN), interval_(DEFAULT_INTERVAL){} IDGenerator(const IDGenerator& obj); IDGenerator& operator=(const IDGenerator& obj); unsigned int current_; unsigned int interval_; protected: void setOrigin(); void setInterval(); public: static IDGenerator& getInstance(); unsigned int getID(); unsigned int getCurrent(); unsigned int getNext(); }; } #endif //__IDGENERATOR_HPP__
- idgenerator.cpp
#include "idgenerator.hpp" DECS::IDGenerator& DECS::IDGenerator::getInstance() { static IDGenerator instance; return instance; } unsigned int DECS::IDGenerator::getID() { this->current_ += this->interval_; return this->current_; } unsigned int DECS::IDGenerator::getCurrent() { return this->current_; } unsigned int DECS::IDGenerator::getNext() { return this->current_ + this->interval_; }
DEFAULT_ORIGIN = 0とかとしているのに1originなのは、なんだかなとは思うがとりあえず今は気にしないことにした。
実際に次のようなmain関数を書き、動かしてみた。
- main.cpp
#include #include #include "idgenerator.hpp" using namespace std; using namespace DECS; int main(int argc, char* argv[]) { IDGenerator& id = IDGenerator::getInstance(); cout << "id's Current ID : " << id.getCurrent() << endl; cout << "id's Next ID : " << id.getNext() << endl; cout << "id's Generate ID : " << id.getID() << endl; IDGenerator& id_2 = IDGenerator::getInstance(); cout << "id_2's Current ID : " << id_2.getCurrent() << endl; cout << "id_2's Next ID : " << id_2.getNext() << endl; cout << "id_2's Generate ID : " << id_2.getID() << endl; return EXIT_SUCCESS; }
実行結果は次のようになる。
id's Current ID : 0 id's Next ID : 1 id's Generate ID : 1 id_2's Current ID : 1 id_2's Next ID : 2 id_2's Generate ID : 2
確かに一つのインスタンスを使用しているようだ。
今回のソースはこちらから→idgenerator.tgz
コメント