Singleton パターン

Singleton パターン - Wikipedia

そのクラスのインスタンスが1つしかないことを保証。一見簡単に書けるけど、単純に書いてしまうと(以下の例はすべて)マルチスレッド化した際に破たんするという実は奥が深いパターン。
参考LINK

  1. マルチスレッドにおける singleton
  2. Singletonパターン
#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;
}
#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;
}