您的位置:首页 > 其它

Singleton template

2013-07-05 11:49 295 查看
共享一个Singleton template的实现:

Singleton.hpp如下

/************************************************************************
* Template of Singleton, threads safe.
* by xiuleili 2013-7-5
************************************************************************/
#pragma once
#include <memory>

#ifdef WIN32
#include "ResGuard.hpp"
#else
#include "ResGuard_linux.hpp"
#endif

template <class T>
class Singleton
{
public:
// return instance of the singleton
static inline T* instance(){
if( 0 == _instance.get() )
{
ResGuard::Lock gd(_rs);
if( 0== _instance.get())
{
_instance.reset ( new T);
}
}
return _instance.get();
}

private:
Singleton(void){}
~Singleton(void){}
Singleton(const Singleton&){}
Singleton & operator= (const Singleton &){}

static std::auto_ptr<T> _instance; // auto_ptr used for release the resource.
static ResGuard _rs;               //
};

template <class T>
std::auto_ptr<T> Singleton<T>::_instance;

template <class T>
ResGuard Singleton<T>::_rs;

// use this macro to declare a singleton
#define DECLARE_SINGLETON_CLASS( type ) \
friend class std::auto_ptr< type >;\
friend class Singleton< type >;

// How to use:
// class A{
// private:
//     A(){}
//     A(const A &){}
//     ~A(){}
//     A & operator=(const A &){}
//     DECLARE_SINGLETON_CLASS(A);
// };
//
// declare the singleton:
// typedef Singleton<A> theA;

//
// call it somewhere like this:
// theA::instance()->foo();


Resguard.hpp

/*
* Implementation of ResGuard on Windows.
* see <<windows kernal var cpp>>
* by xiuleili 2013-7-5
*/

#pragma once
#ifndef _UNIX
#include <windows.h>
///////////////////////////////////////////////////////////////////////////////

// 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 ResGuard {
public:
ResGuard()  { m_guardcount = 0; InitializeCriticalSection(&m_cs); }
~ResGuard() { DeleteCriticalSection(&m_cs); }

// IsGuarded is used for debugging
bool isgurded() const { return(m_guardcount > 0); }

public:
class Lock {
public:
Lock(ResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
~Lock() { m_rg.Unguard(); }

private:
ResGuard& m_rg;
};

private:
void Guard()   { EnterCriticalSection(&m_cs); m_guardcount++; }
void Unguard() { m_guardcount--; LeaveCriticalSection(&m_cs); }

// Guard/Unguard can only be accessed by the nested CGuard class.
friend class ResGuard::Lock;

private:
CRITICAL_SECTION m_cs;
long m_guardcount;   // # of EnterCriticalSection calls
};
#endif


Resguard_linux.hpp

/*
* implementation of ResGuard.
* See <POSIX Muti-threads programming>
* by xiuleili 2013-7-5
*/

#pragma once
#include <pthread.h>

// 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 ResGuard {
public:
ResGuard()  { m_guardcount = 0; pthread_mutex_init(&m_cs, NULL); }
~ResGuard() { pthread_mutex_destroy(&m_cs); }

// IsGuarded is used for debugging
bool isgurded() const { return(m_guardcount > 0); }

public:
class Lock {
public:
Lock(ResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
~Lock() { m_rg.Unguard(); }

private:
ResGuard& m_rg;
};

private:
void Guard()   { pthread_mutex_lock(&m_cs); m_guardcount++; }
void Unguard() { m_guardcount--; pthread_mutex_unlock(&m_cs); }

// Guard/Unguard can only be accessed by the nested Guard class.
friend class ResGuard::Lock;

private:
pthread_mutex_t m_cs;
long m_guardcount;   // # of EnterCriticalSection calls
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: