一个比较完善的C++ Singleton模式类

转载地址:http://hi.baidu.com/uxufgfwvmhfitzr/item/6fd0b82f49aa1fd5a417b630


------------------------------目录------------------------------ 

本文的主要内容为: 
1、Singleton模式的基类 
2、基本的Singleton容器 
3、Singleton模板 
4、引入线程保护代码 
5、完整的代码 
6、如何使用 

------------------------------Singleton模式的基类------------------------------ 
1、Singleton模式的基类 
首先需要统一Singleton类家族的风格,我们用宏定义全权实现构造函数、析构函数和静态的GetInstance()函数。但每一个Singleton也许有其自己的个性,在构造和析构的时候,可能会有额外的操作,我们将其延伸至以下两个纯虚函数中来,由每个Singleton类自己去完成。 
class SinglePattern 

protected: 
virtual void InitialInstance() = 0; 
virtual void DisposeInstance() = 0; 
}; 

------------------------------基本的Singleton容器------------------------------ 
2、基本的Singleton容器 
我们使用auto_ptr来管理指针,使之在程序结束时会正确的得到析构。 
以下为基本的一个Singleton容器,其所容指针即为自己的一个实例。 
class Singleton 

friend class auto_ptr<Singleton>; 
protected: 
static auto_ptr<Singleton> m_Instance; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static Singleton* __fastcall GetInstance() 

if(m_Instance.get() == NULL) 

m_Instance.reset(new Singleton()); 

return m_Instance.get(); 

}; 
auto_ptr<Singleton> Singleton::m_Instance; 

------------------------------Singleton模板------------------------------ 
3、Singleton模板 
如果我们对每一个Singleton类都向上面所写那样,我们需要做很多重复工作。现在我们使用模板类来包装一下。 
我们只需要将上面的代码,用auto_ptr管理的指针改成模板代码即可,程序代码如下: 
template <class T> 
class Singleton 

friend class auto_ptr<T>; 
protected: 
static auto_ptr<T> m_Instance; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static T* __fastcall GetInstance() 

if(m_Instance.get() == NULL) 

m_Instance.reset(new T()); 

return m_Instance.get(); 

}; 
template<class T> 
auto_ptr<T> Singleton<T>::m_Instance; 

实际上你可以看见,如果编写Singleton<Singleton>即变成了基本的Singleton。 

------------------------------引入线程保护代码------------------------------ 
4、引入线程保护代码 
上面的代码在单线程中可以很好的工作,但在多线程环境中,会产生实例被析构再构造的假Singleton类。这里我只引入一个简单的线程保护代码做个示例: 
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(); } 
protected: 
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 
}; 

------------------------------完整的代码------------------------------ 
5、完整的代码 
以下是完整的代码,在C++Builder 6, Windows XP编译通过。 
#pragma once 
#include <Windows.h> 
#include <memory> //线程安全使用的头文件 
#ifndef SingletonH 
#define SingletonH 

using namespace std; 

// Base SinglePattern Class 
class SinglePattern 

protected: 
virtual void InitialInstance() = 0; 
virtual void DisposeInstance() = 0; 
}; 

// Thread Safe Class 
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(); } 
protected: 
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 
}; 

// Singleton Container 
template <class T> 
class Singleton 

friend class auto_ptr<T>; 
protected: 
static auto_ptr<T> m_Instance; 
static CResGuard _rs; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static T* __fastcall GetInstance() 

CResGuard::CGuard gd(_rs); 
if(m_Instance.get() == NULL) 

m_Instance.reset(new T()); 

return m_Instance.get(); 

}; 
template <class T> 
CResGuard Singleton<T>::_rs; 
template<class T> 
auto_ptr<T> Singleton<T>::m_Instance; 

// MACRO of Singleton Pattern to use 
#define DECLARE_SINGLETON(type) \ 
friend class auto_ptr<type>; \ 
friend class Singleton<type>; \ 
public: \ 
static type *GetInstance() \ 
{ \ 
return Singleton<type>::GetInstance(); \ 
} \ 
protected: \ 
__fastcall type() \ 
{ \ 
InitialInstance(); \ 
} \ 
public: \ 
virtual ~type() \ 
{ \ 
DisposeInstance(); \ 

#endif 

------------------------------如何使用------------------------------ 
6、如何使用 
在你自己需要实现Singleton模式的类,使用宏定义,并实现两个纯虚函数,即可。 
以下为一个使用示例: 
class MySingle : public SinglePattern 

DECLARE_SINGLETON(MySingle) 
protected: 
virtual void InitialInstance(){} 
virtual void DisposeInstance(){} 
public: 
void Run(){}; 
}; 

int main(int argc, char* argv[]) 

MySingle::GetInstance()->Run(); 
return 0; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值