평상시 자주 사용하던 단일체를 조금 확장 시켜 봤습니다. 저 같은 경우에 전역 변수를 대체해서 단일체를 사용하는데 마지막에 단일체를 깔끔하게 정리하고자 단일체 리스트를 만들고 자동 파괴 기능을 넣었습니다.
다음은 소스
// sisingleton.h
#ifndef __SI_SINGLETON_H__
#define __SI_SINGLETON_H__
#pragma warning( disable : 4876 )
#include <list>
#include <assert.h>
// SiSingleton ****************************************************************
#define SI_DECLEAR_SINGLETON( a )\
public:\
static a* Instance();\
virtual void ReleaseInstance();\
private:\
static a* m_pkSingleton_Instance;\
#define SI_IMPLEMENT_SINGLETON( a )\
a* a::m_pkSingleton_Instance = 0;\
a* a::Instance()\
{\
if ( !m_pkSingleton_Instance )\
{\
m_pkSingleton_Instance = new a;\
assert( m_pkSingleton_Instance!=0 && "error " #a "::Instance() failed" );\
}\
return m_pkSingleton_Instance;\
}\
void a::ReleaseInstance()\
{\
if ( m_pkSingleton_Instance )\
{\
delete m_pkSingleton_Instance;\
m_pkSingleton_Instance = 0;\
}\
}
class SiSingleton
{
protected:
typedef std::list< SiSingleton* > SI_SINGLETON_LIST;
SiSingleton();
virtual ~SiSingleton();
public:
virtual void ReleaseInstance() = 0;
static void ReleaseAll();
private:
static SI_SINGLETON_LIST ms_lSingleton;
};
#endif//__SI_SINGLETON_H__
// sisingleton.cpp
#include "SiSingleton.h"
// SiSingleton ****************************************************************
SiSingleton::SI_SINGLETON_LIST SiSingleton::ms_lSingleton;
SiSingleton::SiSingleton()
{
ms_lSingleton.push_back( this );
}
SiSingleton::~SiSingleton()
{
SI_SINGLETON_LIST::iterator isingleton = ms_lSingleton.begin();
while ( isingleton != ms_lSingleton.end() )
{
if ( (*isingleton) == this ) break;
}
assert( isingleton != ms_lSingleton.end() && "isingleton == ms_lSingleton.end()" );
ms_lSingleton.erase( isingleton );
}
void SiSingleton::ReleaseAll()
{
SI_SINGLETON_LIST::iterator isingleton = ms_lSingleton.begin();
while ( isingleton != ms_lSingleton.end() )
{
(*isingleton++)->ReleaseInstance();
}
ms_lSingleton.clear();
}
소스 끝
사용한 STL 라이브러리는 STLport입니다. 물론 SGI STL에서도 돌아 갈텐데 VC 6.0이랑 안맞아서 메모리가 줄줄 세는군요. 사용방법은 단일체를 만들 넘에게 SiSingletion을 상속 시키면 되고 마지막에 모든 단일체를 파괴 할때는 SiSingletion::ReleaseAll(); 해주면 됩니다.
[GPG 1 글 1.3] 단일체 확장
Moderator: 류광