c++設計モードの単品モード


単品モードはすべての設計モードの中で最も簡単なものであるべきですが、不適切な使用で多くの問題が発生する場合は、単品モードを分析します.
役割:classが1つのエンティティ(instance)のみであることを保証し、グローバルで一意のアクセスポイントを提供します.
適用:
1、1つのクラス(オブジェクト)について、比較的大きい(占有するシステムリソースが非常に多い)場合、これらのリソースがグローバルに共有できる場合はsingletonモードとして設計することができる.2.クラスの場合、インスタンスをカウントする必要があります.Instanceで行うことができ、インスタンスの数を制限することができます.3.1つのクラスについて、そのインスタンスの具体的な動作を制御する必要がある.例えば、返されるインスタンスは実際には自分のサブクラスのインスタンスであることが望ましい.これによりSingletonモードでクライアントコードを透明に保つことができる.まず、単品モードの一般的な書き方を見てみましょう(問題があるかもしれないので、使い方次第です)
//         
/*
  :    class      (instance),               
*/
class singleton
{
public:
	~singleton()
	{//     
	}
	static singleton* getInstance()
	{
		if(_instance == NULL)
		{
			_instance = new singleton();
		}
		return _instance;
	}

private:
	static singleton *_instance;

private:
//                  
	singleton()
	{

	}
	singleton(const singleton&)
	{

	}
	singleton& operator=(const singleton &)
	{

	}
};
singleton *singleton::_instance = NULL;

使用する場合はsingleton::getInstance()を呼び出すだけでsingletonのポインタを取得できますが、使用が完了したらdelete singleton::getInstance()を呼び出す必要があります.リソースを解放します.
上のコードを分析します.
1、手動でリリースする必要がある_Instance、特にインタフェースを行う場合は、delete singleton::getInstance();文.
2、マルチスレッド環境で使用すると、問題がさらに大きくなり、大量のスレッドがnewに呼び出されるとメモリが漏洩し、前後に取得したsingletonオブジェクトが一致しない可能性があります.
上のコードの問題を分析しましたが、どうやって解決すればいいですか?
問題1:リリース
1、delete singleton::getInstance();
2、atexit()関数を登録し、メモリを解放する方法をatexit関数に入れます.この方法は複数の単品を一緒に呼び出します.
void releasefun()
{
	delete singleton::getInstance();
}
//        
atexit(releasefun);

3、スマートポインタ、例えばSTLのauto_を使うptr、私たちのsingletonは
//         
/*
  :    class      (instance),               
*/
#include 
#include 
using namespace std;
class singleton
{
public:
	~singleton()
	{//     
	}
	static singleton* getInstance()
	{
		if(NULL == _instance.get())
		{
			_instance.reset(new singleton);
		}
		return _instance.get();
	}
private:
	static auto_ptr _instance;

private:
//                  
	singleton()
	{

	}
	singleton(const singleton&)
	{

	}
	singleton& operator=(const singleton &)
	{

	}
};
auto_ptr singleton::_instance;


4、c++埋め込みクラスと静的メンバーを利用して自動解放機構を実現する.
//         
/*
  :    class      (instance),               
*/
#include 
#include 
using namespace std;
class singleton
{
public:
	~singleton()
	{//     
	}
	static singleton* getInstance()
	{
		if(_instance == NULL)
		{
			static clearer clr;
			_instance = new singleton();
		}
		return _instance;
	}
private:
	static singleton *_instance;
private:
//                  
	singleton()
	{

	}
	singleton(const singleton&)
	{

	}
	singleton& operator=(const singleton &)
	{

	}
	class clearer
	{
	public:
		clearer(){}
		~clearer()
		{
			if(singleton::getInstance())
			{
				delete singleton::getInstance();
			}
		}
	};
};
singleton *singleton::_instance = NULL;

問題2:マルチスレッドバージョン
有名なデュアル検出ロックメカニズムの導入
static singleton* getInstance()
{
	if(_instance == NULL)
	{
		//     
		if(NULL == _instance)
		{
			_instance = new singleton();
		}
		//     
	}
	return _instance;
}

そこで,我々のマルチスレッドバージョンを導入した:2つの解放メカニズムの前例で述べた34方法を含む
//         
/*
  :    class      (instance),               
*/
#include 
#include 
#include 
using namespace std;

class lockguard
{
private:
	CRITICAL_SECTION m_cs;

public:
	lockguard()
	{
		InitializeCriticalSection(&m_cs);
	}
	~lockguard()
	{
		DeleteCriticalSection(&m_cs);
	}

public:
	class cguard
	{
	public:
		cguard(lockguard &lg)
			:m_lg(lg)
		{
			m_lg.guard();
		}
		~cguard()
		{
			m_lg.unguard();
		}
	private:
		lockguard &m_lg;
	};
private:
	void guard()
	{
		EnterCriticalSection(&m_cs);
	}
	void unguard()
	{
		LeaveCriticalSection(&m_cs);
	}
	friend class lockguard::cguard;
};

class singleton
{
public:
	~singleton()
	{//     
	}

private:
	static lockguard _lg;
	static singleton *_instance;
	
	//static auto_ptr _instance;

private:
//                  
	singleton()
	{

	}
	singleton(const singleton&)
	{

	}
	singleton& operator=(const singleton &)
	{

	}
	class clearer
	{
	public:
		clearer(){}
		~clearer()
		{
			if(singleton::getInstance())
			{
				delete singleton::getInstance();
			}
		}
	};
public:
	static singleton* getInstance()
	{
		if(_instance == NULL)
		{
			lockguard::cguard gd(_lg);
			if(NULL == _instance)
			{
				static clearer clr;			
				_instance = new singleton();
			}
		}
		/*if(NULL == _instance.get())
		{
		_instance.reset(new singleton);
		}*/
		return _instance;
		//return _instance.get();
	}
};
singleton *singleton::_instance = NULL;
lockguard singleton::_lg;
//auto_ptr singleton::_instance;


これで私たちのsingletonモードは基本的に終わりました.このモードには多くのc++の深い知識が含まれています.