C++シングルケースモード(自動レリーズインスタンス)


最も基本的な実装方法:
#include 
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL )
		{
			m_Instance = new Singleton ();
		}
		return m_Instance;
	}

	static void DestoryInstance()
	{
		if (m_Instance != NULL )
		{
			delete m_Instance;
			m_Instance = NULL ;
		}
	}

	// This is just a operation example
	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;
};

Singleton *Singleton ::m_Instance = NULL;

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<GetTest()<

欠点:
1:醜いだけでなく、間違いやすい.このような付加コードは忘れやすく、delete後にGetInstance関数を呼び出すコードがないことも保証しにくいからです.
2:マルチスレッドの場合、Singletonインスタンスを複数作成できます
3:ファイルを閉じ、外部リソース、データベースリンクなどを解放すると、上記のコードはこの要求を実現できません.
マルチスレッドの改良バージョン:
#include 
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL )
		{
			Lock(); // C++     Lock  ,       Lock,  Boost,       
			if (m_Instance == NULL )
			{
				m_Instance = new Singleton ();
			}
			UnLock(); // C++     Lock  ,       Lock,  Boost,       
		}
		return m_Instance;
	}

	static void DestoryInstance()
	{
		if (m_Instance != NULL )
		{
			delete m_Instance;
			m_Instance = NULL ;
		}
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 0; }
	static Singleton *m_Instance;
	int m_Test;
};

Singleton *Singleton ::m_Instance = NULL;

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<GetTest()<

分析:
2回行いましたm_Instance==NULLの判断は,Javaの一例モード実装時に用いられるいわゆる「ダブルチェック」メカニズムを参考にしたものである.1回のロックとロック解除は対応する代価を払う必要があるため、2回の判断を行うことで、複数回のロックとロック解除操作を避けることができ、スレッドの安全を保証することができる.
インスタンスバージョンの自動破棄:
#include 
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public :
		~GC()
		{
			// We can destory all the resouce here
			if (m_Instance != NULL )
			{
				cout<< "Here is the test" <GetTest()<

説明:
このクラスに適当な時に自分を削除することを自分で知らせます.あるいは,自分の削除操作をシステム内の適切な点に掛け,適切なときに自動的に実行させる.プログラムが終了すると,システムはすべてのグローバル変数を自動的に解析することを知っている.実際、システムは、これらの静的メンバーもグローバル変数であるように、すべてのクラスの静的メンバー変数を解析します.この特徴を用いて,このような静的メンバー変数を単一クラスで定義することができ,その唯一の作業は,構造関数で単一クラスのインスタンスを削除することである.