温故而知新,总结了多种单例模式的写法,考虑上多线程没有非常完美的,各取所需吧
//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
  {
public:
static Singleton* getSingleton()
 {
if(NULL==m_singleton)
 {
m_singleton=new Singleton();
}
return m_singleton;
}
private:
 Singleton() {}
 ~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 .

//2.-----------
class Singleton
  {
public:
staitc Singleton* getSingleton();
private:
Singleton();
~Singleton();
static Singleton* m_singleton;
class Garbo//Just used for delete the static var
 {
public:
Garbo();
~Garbo()
 {
if(Singleton::m_singleton!=NULL)
 {
delete Singleton::m_singleton;
Singleton::m_singleton=NULL;
}
}
}
staitc Garbo m_garbo;//define a static var,
}
//singleton.cpp
Garbo Singleton::m_garbo;
//

//3.---------------
class Singleton
  {
public:
staitc Singleton* getSingletonPtr()
 {
if(NULL==m_singleton)
 {
m_singleton.reset(new Singleton);
}
return m_singleton.get();
}
protected:
 Singleton() {}
 virtual ~Singleton() {}
friend class auto_ptr<Singleton>;
static auto_ptr<Singleton> m_singleton;
};

//singleton.cpp
auto_ptr<Singleton> Singleton::m_singleton=NULL;


//4.
class Singleton
  {
public:
static Singleton* getSingletonPtr()
 {
staitc Singleton singleton;
return &singleton;
}
private:
 Singleton() {}
 ~Singleton() {}
}

//5.
class Singleton
  {
public:
staitc Singleton& getSingleton
 {
return m_singleton;
}
private:
staitc Singleton m_singleton;
 Singleton() {}
}


//6.---------thread safe

#pragma once
#include <memory>
using namespace std;
#include "Interlocked.h"
using namespace C2217::Win32;
namespace C2217
  {
namespace Pattern
  {
template <class T>
class Singleton
  {
public:
static inline T* instance();
private:
 Singleton(void) {}
 ~Singleton(void) {}
 Singleton(const Singleton&) {}
 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()
  {
if( 0 == _instance.get() )
 {
CResGuard::CGuard gd(_rs);
if( 0== _instance.get())
 {
_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 类主要的功能是线程访问同步,代码如下:
 /**//******************************************************************************

******************************************************************************/
#pragma once
 /**////////////////////////////////////////////////////////////////////////////////
// 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.
 class CResGuard {
public:
 CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }
 ~CResGuard() { DeleteCriticalSection(&m_cs); }
// IsGuarded is used for debugging
 BOOL IsGuarded() const { return(m_lGrdCnt > 0); }
public:
 class CGuard {
public:
 CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
 ~CGuard() { m_rg.Unguard(); }
private:
CResGuard& m_rg;
};
private:
 void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; }
 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
};

//7. most used
template <typename T>
class Singleton
  {
public :
static T& getSingleton()
 {
return *m_singlon;
}

static T* getSingletonPtr()
 {
return m_singlon;
}
protected:

Singleton()
 {
m_singlon=static_cast<T*>(this);
}

~Singleton()
 {
m_singlon=NULL;
}
private:
 Singleton(const Singleton&) {}

 Singleton& operator=(const Singleton&) {}

static T* m_singlon;
};

template<typename T>
T* Singleton<T>::m_singlon = NULL;
|