??????有了CComObjectRootBase、CComObjectRootEx和線程模型特征類這些基礎(chǔ)原料,CComObject和它的伙伴們便可以自由的發(fā)揮它們的想象了。
1.CComObject —— 普通堆對(duì)象??????
???下面是精簡(jiǎn)的CComObject模板類的定義:??????
template?
<
class
?Base
>
class
?CComObject?:?
public
?Base
{
public
:
????CComObject(
void
*
?
=
?NULL)?
throw
()
????{
????????_pAtlModule
->
Lock();
????}
????
????virtual
?
~
CComObject()?
throw
()
????{
????????FinalRelease();
??????? _pAtlModule
->
Unlock();
????}
????
??? STDMETHOD_(ULONG,?AddRef)()?{
return
?InternalAddRef();}
????STDMETHOD_(ULONG,?Release)()
????{
????????ULONG?l?
=
?InternalRelease();
????????
if
?(l?
==
?
0
)
????????????delete?
this
;
????????
return
?l;
????}
????
????STDMETHOD(QueryInterface)(REFIID?iid,?
void
?
**
?ppvObject)?
throw
()
????{
return
?_InternalQueryInterface(iid,?ppvObject);}
????
????
static
?HRESULT?WINAPI?CreateInstance(CComObject
<
Base
>**
?pp)?
throw
();
};
“普通堆對(duì)象”是使用最為頻繁的類,它有如下特征:
(1)在堆中分配內(nèi)存 —— 計(jì)數(shù)歸零時(shí)用delete銷毀
(2)支持獨(dú)立存在的對(duì)象 —— 使用InternalXXX來(lái)實(shí)現(xiàn)IUnknown功能
(3)產(chǎn)生時(shí)鎖定服務(wù)器,銷毀時(shí)解鎖服務(wù)器 —— 適用于大多數(shù)COM對(duì)象
2. CComAggObject —— 被聚合堆對(duì)象
template?
<
class
?contained
>
class
?CComAggObject?:
????
public
?IUnknown,
????
public
?CComObjectRootEx
<
?typename?contained::_ThreadModel::ThreadModelNoCS?
>
{
public
:
????CComAggObject(
void
*
?pv)?:?m_contained(pv)
????{
????????_pAtlModule
->
Lock();
????}
????
HRESULT?FinalConstruct()
????{
????????CComObjectRootEx
<
contained::_ThreadModel::ThreadModelNoCS
>
::FinalConstruct();
????????
return
?m_contained.FinalConstruct();
????}
????
void
?FinalRelease()
????{
????????CComObjectRootEx
<
contained::_ThreadModel::ThreadModelNoCS
>
::FinalRelease();
????????m_contained.FinalRelease();
????}
???
?
virtual
?
~
CComAggObject()
????{
???????
?FinalRelease();
????????_pAtlModule
->
Unlock();
????}
????STDMETHOD_(ULONG,?AddRef)()?{
return
?InternalAddRef();}
????STDMETHOD_(ULONG,?Release)()
????{
????????ULONG?l?
=
?InternalRelease();
????????
if
?(l?
==
?
0
)
????????????delete?
this
;
????????
return
?l;
????}
????STDMETHOD(QueryInterface)(REFIID?iid,?
void
?
**
?ppvObject)
????{
????????HRESULT?hRes?
=
?S_OK;
????????
if
?(InlineIsEqualUnknown(iid))
????????{
????????????
*
ppvObject?
=
?(
void
*
)(IUnknown
*
)
this
;
????????????AddRef();
????????}
????????
else
????????????hRes?
=
?m_contained._InternalQueryInterface(iid,?ppvObject);
????????
return
?hRes;
????}
???
?
static
?HRESULT?WINAPI?CreateInstance(LPUNKNOWN?pUnkOuter,?CComAggObject
<
contained
>**
?pp);
????CComContainedObject
<
contained
>
?m_contained;
};
? CComAggObject有如下特征:
(1)在堆中分配內(nèi)存
(2)支持被聚合聚合的對(duì)象
???????????實(shí)現(xiàn)了兩份IUnknown:CComAggObject實(shí)現(xiàn)了內(nèi)部聚合類真正的IUnknown,它管理對(duì)象的生存期,并且完成接口查詢(通過(guò)contained對(duì)象的_InternalQueryInterface);contained對(duì)象實(shí)現(xiàn)了具有轉(zhuǎn)發(fā)功能的IUnknown,它將所有的調(diào)用轉(zhuǎn)發(fā)給CComAggObject在構(gòu)造函數(shù)中收到的外部IUnknown指針。
(3)產(chǎn)生時(shí)鎖定服務(wù)器,銷毀時(shí)解鎖服務(wù)器
3. CComTearOffObject —— tear-off 對(duì)象
template?
<
class
?Base
>
class
?CComTearOffObject?:?
public
?Base
{
public
:
????CComTearOffObject(
void
*
?pv)
????{
????????m_pOwner?
=
?reinterpret_cast
<
Base::_OwnerClass
*>
(pv);
????????m_pOwner
->
AddRef();
????}
????
~
CComTearOffObject()
????{
????????FinalRelease();
????????m_pOwner
->
Release();
????}
????STDMETHOD_(ULONG,?AddRef)()?
throw
()?{
return
?InternalAddRef();}
????STDMETHOD_(ULONG,?Release)()?
throw
()
????{
????????ULONG?l?
=
?InternalRelease();
????????
if
?(l?
==
?
0
)
????????????delete?
this
;
????????
return
?l;
????}
????STDMETHOD(QueryInterface)(REFIID?iid,?
void
?
**
?ppvObject)?
throw
()
????{
????????
return
?m_pOwner
->
QueryInterface(iid,?ppvObject);
????}
};
???tear-off對(duì)象有如下特征:
(1)在堆中分配內(nèi)存
(2)支持在ATL組件內(nèi)部使用的tear-off技術(shù)
(3)生成時(shí)鎖定父對(duì)象,銷毀時(shí)解鎖父對(duì)象
(4)生命周期由自己管理,接口查詢委托父對(duì)象
4. CComObjectStack —— 棧對(duì)象
???
template?<class?Base>
class?CComObjectStackEx?:?public?Base
{
public:
????CComObjectStackEx(void*?=?NULL)?
????{?
????????m_hResFinalConstruct?=?FinalConstruct();?
????}
????virtual?~CComObjectStackEx()
????{
??????? FinalRelease();
??? }
????STDMETHOD_(ULONG,?AddRef)()
????{
??????? return?0;
????}
????STDMETHOD_(ULONG,?Release)()
????{
????????return?0;
????}
????STDMETHOD(QueryInterface)(REFIID?iid,?void?**?ppvObject)
????{
????????return?_InternalQueryInterface(iid,?ppvObject);
????}
????HRESULT?m_hResFinalConstruct;
};
???棧對(duì)象有如下特征:
(1)內(nèi)存分配于棧上 —— 不需要對(duì)象考慮釋放問(wèn)題
(2)無(wú)引用計(jì)數(shù)功能
(3)構(gòu)造時(shí)初始化 —— 需要在構(gòu)造函數(shù)調(diào)用后檢查m_hResFinalConstruct,以判斷對(duì)象是否構(gòu)造成功
(4)不鎖定服務(wù)器
5. CComObjectGlobal —— 全局對(duì)象
template?<class?Base>
class?CComObjectGlobal?:?public?Base
{
public:
????CComObjectGlobal(void*?=?NULL)
????{
??????? m_hResFinalConstruct?=?FinalConstruct();
????}
????virtual?~CComObjectGlobal()
????{
?????????????FinalRelease();
????}
????STDMETHOD_(ULONG,?AddRef)()?throw()
????{
????????return?_pAtlModule->Lock();
????}
????STDMETHOD_(ULONG,?Release)()?throw()
????{
????????return?_pAtlModule->Unlock();
????}
????STDMETHOD(QueryInterface)(REFIID?iid,?void?**?ppvObject)?throw()
????{
????????return?_InternalQueryInterface(iid,?ppvObject);
????}
????HRESULT?m_hResFinalConstruct;
};
???
???全局對(duì)象有如下特征:
(1)在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存
(2)初始化時(shí)不鎖定服務(wù)器,引用計(jì)數(shù)變化時(shí)才鎖定或者解鎖服務(wù)器,這使得全局對(duì)象可以被用于全局類廠對(duì)象,以解決服務(wù)器和類廠之間的死鎖問(wèn)題
(3)構(gòu)造方式同棧對(duì)象
???還有一些其它種類的生存期管理類,如CComObjectNoLock、CComObjectCached、CComPolyObject等等,它們也都有自己獨(dú)到的用處,我們也可以根據(jù)自己的需要編寫自定義的類。總之CComObjectRootBase、CComObjectRootEx和線程模型特征類就像是積木一樣,我們可以任意的把它們組合成想要的形狀。
posted on 2007-04-06 15:33
michael 閱讀(3698)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
心得