温故而知新,总结了多种单例模式的写法,考虑上多线程没有非常完美的,各取所需吧
//1.
//Easy ,<<Pattern Design>>
//Q:
//When to free the m_singleton space?
//when to execute the destruct function?
//A:We can call getSingleton() at the end of the progress,
//then delete the pointer and free the space,
//but ,Here is a problem:Someone will call getSingleton() after
//we delete it。How to avoid these?
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
static Singleton* getSingleton()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(NULL==m_singleton)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_singleton=new Singleton();
}
return m_singleton;
}
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton() {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ~Singleton() {}
private:
static Singleton* m_singleton;
};
//singleton.cpp
singleton* Singleton::m_singleton=NULL;
//Because ,at the end of the program, all globle vars will be destructed. ,
//and all the static vars .we can use this point, define a static var in
//the Singleton class ,it is used to delete the Singleton class .
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//2.-----------
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
staitc Singleton* getSingleton();
private:
Singleton();
~Singleton();
static Singleton* m_singleton;
class Garbo//Just used for delete the static var
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
public:
Garbo();
~Garbo()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(Singleton::m_singleton!=NULL)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
delete Singleton::m_singleton;
Singleton::m_singleton=NULL;
}
}
}
staitc Garbo m_garbo;//define a static var,
}
//singleton.cpp
Garbo Singleton::m_garbo;
//
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//3.---------------
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
staitc Singleton* getSingletonPtr()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(NULL==m_singleton)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_singleton.reset(new Singleton);
}
return m_singleton.get();
}
protected:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton() {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) virtual ~Singleton() {}
friend class auto_ptr<Singleton>;
static auto_ptr<Singleton> m_singleton;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//singleton.cpp
auto_ptr<Singleton> Singleton::m_singleton=NULL;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//4.
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
static Singleton* getSingletonPtr()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
staitc Singleton singleton;
return &singleton;
}
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton() {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ~Singleton() {}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//5.
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public:
staitc Singleton& getSingleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
return m_singleton;
}
private:
staitc Singleton m_singleton;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton() {}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//6.---------thread safe
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma once
#include <memory>
using namespace std;
#include "Interlocked.h"
using namespace C2217::Win32;
namespace C2217
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
namespace Pattern
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif) {
template <class T>
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif) {
public:
static inline T* instance();
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton(void) {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ~Singleton(void) {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton(const Singleton&) {}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton & operator= (const Singleton &) {}
static auto_ptr<T> _instance;
static CResGuard _rs;
};
template <class T>
auto_ptr<T> Singleton<T>::_instance;
template <class T>
CResGuard Singleton<T>::_rs;
template <class T>
inline T* Singleton<T>::instance()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif) {
if( 0 == _instance.get() )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
CResGuard::CGuard gd(_rs);
if( 0== _instance.get())
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
_instance.reset ( new T);
}
}
return _instance.get();
}
//Class that will implement the singleton mode,
//must use the macro in it's delare file
#define DECLARE_SINGLETON_CLASS( type ) \
friend class auto_ptr< type >;\
friend class Singleton< type >;
}
}
// CresGuard 类主要的功能是线程访问同步,代码如下:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//******************************************************************************
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
******************************************************************************/
#pragma once
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////////
// Instances of this class will be accessed by multiple threads. So,
// all members of this class (except the constructor and destructor)
// must be thread-safe.
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class CResGuard {
public:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ~CResGuard() { DeleteCriticalSection(&m_cs); }
// IsGuarded is used for debugging
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) BOOL IsGuarded() const { return(m_lGrdCnt > 0); }
public:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) class CGuard {
public:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ~CGuard() { m_rg.Unguard(); }
private:
CResGuard& m_rg;
};
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; }
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); }
// Guard/Unguard can only be accessed by the nested CGuard class.
friend class CResGuard::CGuard;
private:
CRITICAL_SECTION m_cs;
long m_lGrdCnt; // # of EnterCriticalSection calls
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//7. most used
template <typename T>
class Singleton
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
public :
static T& getSingleton()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
return *m_singlon;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
static T* getSingletonPtr()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
return m_singlon;
}
protected:
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
Singleton()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_singlon=static_cast<T*>(this);
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
~Singleton()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
m_singlon=NULL;
}
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton(const Singleton&) {}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Singleton& operator=(const Singleton&) {}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
static T* m_singlon;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename T>
T* Singleton<T>::m_singlon = NULL;
|