在ATL中,类厂是计数的

在ATL中,类厂是计数的。

1.   CComCoClass
template   <class   T,   const   CLSID*   pclsid   =   &CLSID_NULL>
class   CComCoClass
{
public:
DECLARE_CLASSFACTORY()

...
}

2.  
#define   DECLARE_CLASSFACTORY()   DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory)

3.   类厂的_ClassFactoryCreatorClass
#if   defined(_WINDLL)   ¦   defined(_USRDLL)
#define   DECLARE_CLASSFACTORY_EX(cf)   typedef   ATL::CComCreator <   ATL:: CComObjectCached <   cf   >   >   _ClassFactoryCreatorClass;
#else
//   don 't   let   class   factory   refcount   influence   lock   count
#define   DECLARE_CLASSFACTORY_EX(cf)   typedef   ATL::CComCreator <   ATL:: CComObjectNoLock <   cf   >   >   _ClassFactoryCreatorClass;
#endif

4.1   对于in-pro
template    < class    Base >  
class    CComObjectCached   :    public    Base 

public
    typedef   Base   _BaseClass; 
    CComObjectCached(
void *     =    NULL){} 
    
//    Set   refcount   to   -(LONG_MAX/2)   to   protect   destruction   and   
    
//    also   catch   mismatched   Release   in   debug   builds 
     ~ CComObjectCached() 
    { 
        m_dwRef   
=     - (LONG_MAX / 2 ); 
        FinalRelease(); 
#ifdef   _ATL_DEBUG_INTERFACES 
        _AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown()); 
#endif  
    } 
    
// If   InternalAddRef   or   InternalRelease   is   undefined   then   your   class 
    
// doesn 't   derive   from   CComObjectRoot 
    STDMETHOD_(ULONG,   AddRef)() 
    { 
        m_csCached.Lock(); 
        ULONG   l   
=    InternalAddRef(); 
        
if    (m_dwRef    ==     2
        _pAtlModule
->  Lock(); 
        m_csCached.Unlock(); 
        
return    l; 
    } 
    STDMETHOD_(ULONG,   Release)() 
    { 
        m_csCached.Lock(); 
        InternalRelease(); 
        ULONG   l   
=    m_dwRef; 
        m_csCached.Unlock(); 
        
if    (l    ==     0
        delete   
this
        
else     if    (l    ==     1
        _pAtlModule
->  Unlock(); 
        
return    l; 
    } 
    
// if   _InternalQueryInterface   is   undefined   then   you   forgot   BEGIN_COM_MAP 
    STDMETHOD(QueryInterface)(REFIID   iid,    void     **    ppvObject) 
    {
return    _InternalQueryInterface(iid,   ppvObject);} 
    CComGlobalsThreadModel::AutoCriticalSection   m_csCached; 
}; 

4.2   对于local   server   or   service
template    < class    Base >  
class    CComObjectNoLock   :    public    Base 

public
    typedef   Base   _BaseClass; 
    CComObjectNoLock(
void *     =    NULL){} 
    
//    Set   refcount   to   -(LONG_MAX/2)   to   protect   destruction   and   
    
//    also   catch   mismatched   Release   in   debug   builds 
     ~ CComObjectNoLock() 
    { 
        m_dwRef   
=     - (LONG_MAX / 2 ); 
        FinalRelease(); 
#ifdef   _ATL_DEBUG_INTERFACES 
        _AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown()); 
#endif  
    } 

    
// If   InternalAddRef   or   InternalRelease   is   undefined   then   your   class 
    
// doesn 't   derive   from   CComObjectRoot 
    STDMETHOD_(ULONG,   AddRef)()   { return    InternalAddRef();} 
    STDMETHOD_(ULONG,   Release)() 
    { 
        ULONG   l   
=    InternalRelease(); 
        
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);} 
}; 

由此可见, 在ATL中类厂是计数的。
只不过对于in-pro,   只有当m_dwRef由1-> 2时,才lock   server;当m_dwRef由2-> 1时,就unlock   server;通过这种手段来避免“ 自相矛盾”。

而对于local   server   or   service,   计数但不lock/unlock   server. 
 

你可能感兴趣的:(server,service,null,delete,Class)