使用ATL创建单件

#ifndef __SINGLETON_H__
#define  __SINGLETON_H__

template 
< class  Base >
class  CComObjectSingleton :  public  Base
{
public:
    typedef Base _BaseClass;
    typedef typename _BaseClass::_CritSec _CritSec;
    CComObjectSingleton(
void* = NULL)
    
{
        _Module.Lock();
    }

    
// Set refcount to 1 to protect destruction
    ~CComObjectSingleton()
    
{
        m_dwRef 
= 1L;
        FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
        _Module.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
        _Module.Unlock();
    }

    
//If InternalAddRef or InternalRelease is undefined then your class
    
//doesn't derive from CComObjectRoot
    STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
    STDMETHOD_(ULONG, Release)()
    
{
        ULONG l;
        s_critsec.Lock();
        l 
= InternalRelease();
        
if (l == 0)
        
{
            s_pThis 
= NULL;
        }

        s_critsec.Unlock();
        
if (l == 0)
            delete 
this;
        
return l;
    }

    
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
    STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
    
{return _InternalQueryInterface(iid, ppvObject);}
    template 
<class Q>
        HRESULT STDMETHODCALLTYPE QueryInterface(Q
** pp)
    
{
        
return QueryInterface(__uuidof(Q), (void**)pp);
    }

    
public:
    
static _CritSec     s_critsec;
    
static _BaseClass* s_pThis;
}
;

template
< class  Base >
CComObjectSingleton
< Base > ::_BaseClass  *
CComObjectSingleton
< Base > ::s_pThis  =  NULL;

template
< class  Base >
CComObjectSingleton
< Base > ::_CritSec
CComObjectSingleton
< Base > ::s_critsec;

template 
< class  T1 >
class  CComSingletonCreator
{
public:
    
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
    
{
        ATLASSERT(
*ppv == NULL);
        HRESULT hRes 
= E_OUTOFMEMORY;
        T1
* p = NULL;
        T1::s_critsec.Lock();
        
if (T1::s_pThis != NULL)
        
{
            hRes 
= T1::s_pThis->QueryInterface(riid, ppv);
        }

        
else
        
{
            ATLTRY(p 
= new T1(pv));
            
if (p != NULL)
            
{
                p
->SetVoid(pv);
                p
->InternalFinalConstructAddRef();
                hRes 
= p->FinalConstruct();
                p
->InternalFinalConstructRelease();
                
if (hRes == S_OK)
                    hRes 
= p->QueryInterface(riid, ppv);
                
if (hRes != S_OK)
                    delete p;
            }

            
if (hRes == S_OK)
            
{
                T1::s_pThis 
= p;
            }

        }

        T1::s_critsec.Unlock();
        
return hRes;
    }

}
;

#define  DECLARE_SINGLETON(x) public:
typedef CComCreator2
<  CComSingletonCreator <  CComObjectSingleton <  x  >   > , CComFailCreator < CLASS_E_NOAGGREGATION >    >  _CreatorClass;

#endif   // __SINGLETON_H__

用法:

class ATL_NO_VTABLE CTest:

     public CComObjectRootEx<CComMultiThreadModel>,
     public CComCoClass<CTest, &CLSID_GUID>,

{

public:

   DECLARE_SINGLETON(CTest)


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值