Singleton template

共享一个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
};



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值