程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Singleton template

Singleton template

編輯:C++入門知識

共享一個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(); 

/************************************************************************
* 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 

/*
* 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  
}; 

/*
* 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
};

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved