有了CComObjectRootBase、CComObjectRootEx和线程模型特征类这些基础原料,CComObject和它的伙伴们便可以自由的发挥它们的想象了。
1.CComObject —— 普通堆对象
下面是精简的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
();
};
“普通堆对象”是使用最为频繁的类,它有如下特征:
(1)在堆中分配内存 —— 计数归零时用delete销毁
(2)支持独立存在的对象 —— 使用InternalXXX来实现IUnknown功能
(3)产生时锁定服务器,销毁时解锁服务器 —— 适用于大多数COM对象
2. CComAggObject —— 被聚合堆对象
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)在堆中分配内存
(2)支持被聚合聚合的对象
实现了两份IUnknown:CComAggObject实现了内部聚合类真正的IUnknown,它管理对象的生存期,并且完成接口查询(通过contained对象的_InternalQueryInterface);contained对象实现了具有转发功能的IUnknown,它将所有的调用转发给CComAggObject在构造函数中收到的外部IUnknown指针。
(3)产生时锁定服务器,销毁时解锁服务器
3. CComTearOffObject —— tear-off 对象
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对象有如下特征:
(1)在堆中分配内存
(2)支持在ATL组件内部使用的tear-off技术
(3)生成时锁定父对象,销毁时解锁父对象
(4)生命周期由自己管理,接口查询委托父对象
4. CComObjectStack —— 栈对象
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;
};
栈对象有如下特征:
(1)内存分配于栈上 —— 不需要对象考虑释放问题
(2)无引用计数功能
(3)构造时初始化 —— 需要在构造函数调用后检查m_hResFinalConstruct,以判断对象是否构造成功
(4)不锁定服务器
5. CComObjectGlobal —— 全局对象
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;
};
全局对象有如下特征:
(1)在全局数据区分配内存
(2)初始化时不锁定服务器,引用计数变化时才锁定或者解锁服务器,这使得全局对象可以被用于全局类厂对象,以解决服务器和类厂之间的死锁问题
(3)构造方式同栈对象
还有一些其它种类的生存期管理类,如CComObjectNoLock、CComObjectCached、CComPolyObject等等,它们也都有自己独到的用处,我们也可以根据自己的需要编写自定义的类。总之CComObjectRootBase、CComObjectRootEx和线程模型特征类就像是积木一样,我们可以任意的把它们组合成想要的形状。
posted on 2007-04-06 15:33
michael 阅读(3654)
评论(0) 编辑 收藏 引用 所属分类:
心得