Singleton パターン
そのクラスのインスタンスが1つしかないことを保証。一見簡単に書けるけど、単純に書いてしまうと(以下の例はすべて)マルチスレッド化した際に破たんするという実は奥が深いパターン。
参考LINK
- 実装その1:インスタンスを静的ローカル変数化
#include<iostream> using namespace std; //Singleton class Singleton { public : static Singleton & GetInstance(){ static Singleton singleton; return singleton; } void PrintValue(){ cout << value_ << endl; value_++; } private : int value_; Singleton() : value_(0){} ~Singleton(){} Singleton(Singleton& singleton){} Singleton& operator=(const Singleton& singleton){} }; //main int main() { cout << "Start" << endl; Singleton & s1 = Singleton::GetInstance(); Singleton & s2 = Singleton::GetInstance(); s1.PrintValue(); s2.PrintValue(); s1.PrintValue(); s2.PrintValue(); cout << "End" << endl; getchar(); return 0; }
- 実装その2:インスタンスを静的メンバ変数化
#include<iostream> using namespace std; //Singleton class Singleton { public : static Singleton & GetInstance(){ if(singleton_ == NULL){ singleton_ = new Singleton(); } return *singleton_; } void PrintValue(){ cout << value_ << endl; value_++; } static void DeleteInstance(){ if(singleton_ != NULL){ delete singleton_; singleton_ = NULL; } } private : int value_; static Singleton *singleton_; Singleton() : value_(0){} ~Singleton(){} Singleton(Singleton& singleton){} Singleton& operator=(const Singleton& singleton){} }; Singleton * Singleton::singleton_ = NULL; //main int main() { cout << "Start" << endl; Singleton & s1 = Singleton::GetInstance(); Singleton & s2 = Singleton::GetInstance(); s1.PrintValue(); s2.PrintValue(); s1.PrintValue(); s2.PrintValue(); cout << "End" << endl; Singleton::DeleteInstance(); Singleton::DeleteInstance(); getchar(); return 0; }
- 実装その3:実装その2をパワーアップ、インスタンスの削除も自動化
#include<iostream> using namespace std; //Singleton & SingletonDestroyer class SingletonDestroyer; class Singleton { public : static Singleton & GetInstance(); void PrintValue(); private : friend class SingletonDestroyer; int value_; static Singleton *singleton_; static SingletonDestroyer destroyer_; Singleton(); ~Singleton(); Singleton(Singleton& singleton); Singleton& operator=(const Singleton& singleton); }; class SingletonDestroyer { public : ~SingletonDestroyer(); void SetSingleton(Singleton & singleton); private: Singleton* singleton_; }; //initialize Singleton * Singleton::singleton_ = NULL; SingletonDestroyer Singleton::destroyer_; //implement Singleton & Singleton::GetInstance() { if(singleton_ == NULL){ singleton_ = new Singleton(); destroyer_.SetSingleton(*singleton_); } return *singleton_; } void Singleton::PrintValue() { cout << value_ << endl; value_++; } Singleton::Singleton() : value_(0) { } Singleton::~Singleton() { } Singleton::Singleton(Singleton& singleton) { } Singleton& Singleton::operator=(const Singleton& singleton) { return *singleton_; } SingletonDestroyer::~SingletonDestroyer(){ if(singleton_ != NULL){ delete singleton_; } } void SingletonDestroyer::SetSingleton(Singleton & singleton) { singleton_ = &singleton; } //main int main() { cout << "Start" << endl; Singleton & s1 = Singleton::GetInstance(); Singleton & s2 = Singleton::GetInstance(); s1.PrintValue(); s2.PrintValue(); s1.PrintValue(); s2.PrintValue(); cout << "End" << endl; getchar(); return 0; }