包容和聚合(COM技术内幕笔记五)
2010-09-13 20:53
459 查看
包容和聚合:
包容和聚合实际上是使一个组件使用另外一个组件的一种技术。在包容的情况下,外部组件将包含内部组件。在聚合的情况下,外部组件聚合内部组件。
在此设想一下,外部组件是我们的要实现的组件,而内部组件是其它要重用的组件。
包容是外部组件包含指向内部组件接口的指针.外部组件相对来说是内部组件的一个客户,它将使用内部组件的接口来实现它自己的接口.
聚合是包容的一个特例,当一个外部组件聚合了某个内部组件的一个接口时,它并没有像包容那样重新实现此接口并明确地将调用请求转发给内部组件。相反,外部组件将直接把内部件的接口指针返回给客户。
在组件CB实现的时候,添加一成员变量:
private:
IY* m_pIY;
对IY接口的Fy函数的实现,与组件CA
不同:
对组件CB新增一成员函数
HRESULT Init();
至于CB的其它实现和CA相同,暂不累叙,如有不清楚的概念请看前一节。
在组件CB的CFactory::CreateInstance函数中加入对Init函数的调用:
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
{
CA* pA = new CA();
if(pA == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pA->Init();
if(FAILED(hr))
{
pA->Release();
return hr;
}
hr = pA->QueryInterface(iid,ppv);
pA->Release();
return hr;
}
在此,就实现了组件CB对组件CA的包容。CB没有自己去实现基类IY的Fy()函数,而是把这个任务交给了组件CA对于Fy()函数的实现。一切的一切都是通过组件CB中的Init函数。通过CoCreateInstance查询组件CA的IY接口。然后返回IY指针,赋给CB的私有成员m_pIY。
通过对于m_pIY的包容,实现了组件的复用。
如何使用包容:
在前一节,建立了一个组件CA,其实现了IX,IY接口。在这一节,暂时把其看作是一内部组件。我们要使用其对IY接口的函数实现
新建一个DLL项目,新建一接口IX,新建一个组件的CLSID。另外,导入CA项目IFACE.h中的IY接口IID和CA组件的CLSID。如下所示:
extern "C"
{
// {3CA3B6D4-799C-4d5d-BF3A-373C4EECE925} 此IX是新建的IID
static const IID IID_IX =
{ 0x3ca3b6d4, 0x799c, 0x4d5d,
{ 0xbf, 0x3a, 0x37, 0x3c, 0x4e, 0xec, 0xe9, 0x25 } };
// {41A5F090-B33A-4ae8-A1BB-EF2D0B4F8B0E} //此IY是从CA中IID_IY的复制
static const IID IID_IY =
{ 0x41a5f090, 0xb33a, 0x4ae8,
{ 0xa1, 0xbb, 0xef, 0x2d, 0xb, 0x4f, 0x8b, 0xe } };
}
// {3D29721C-8D93-4c24-A8A5-4CE01FD9FD00} 这是CB组件新建的CLSID
static const CLSID CLSID_CTANINFACE =
{ 0x3d29721c, 0x8d93, 0x4c24,
{ 0xa8, 0xa5, 0x4c, 0xe0, 0x1f, 0xd9, 0xfd, 0x0 } };
// {282D8F98-BC89-43d5-9225-0B1BB479CBDE} 这是CA组件复制过来的CLSID
static const CLSID CLSID_Component1 =
{ 0x282d8f98, 0xbc89, 0x43d5,
{ 0x92, 0x25, 0xb, 0x1b, 0xb4, 0x79, 0xcb, 0xde } };
包容和聚合实际上是使一个组件使用另外一个组件的一种技术。在包容的情况下,外部组件将包含内部组件。在聚合的情况下,外部组件聚合内部组件。
在此设想一下,外部组件是我们的要实现的组件,而内部组件是其它要重用的组件。
包容是外部组件包含指向内部组件接口的指针.外部组件相对来说是内部组件的一个客户,它将使用内部组件的接口来实现它自己的接口.
聚合是包容的一个特例,当一个外部组件聚合了某个内部组件的一个接口时,它并没有像包容那样重新实现此接口并明确地将调用请求转发给内部组件。相反,外部组件将直接把内部件的接口指针返回给客户。
在组件CB实现的时候,添加一成员变量:
private:
IY* m_pIY;
对IY接口的Fy函数的实现,与组件CA
不同:
对组件CB新增一成员函数
HRESULT Init();
至于CB的其它实现和CA相同,暂不累叙,如有不清楚的概念请看前一节。
在组件CB的CFactory::CreateInstance函数中加入对Init函数的调用:
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
{
CA* pA = new CA();
if(pA == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pA->Init();
if(FAILED(hr))
{
pA->Release();
return hr;
}
hr = pA->QueryInterface(iid,ppv);
pA->Release();
return hr;
}
在此,就实现了组件CB对组件CA的包容。CB没有自己去实现基类IY的Fy()函数,而是把这个任务交给了组件CA对于Fy()函数的实现。一切的一切都是通过组件CB中的Init函数。通过CoCreateInstance查询组件CA的IY接口。然后返回IY指针,赋给CB的私有成员m_pIY。
通过对于m_pIY的包容,实现了组件的复用。
如何使用包容:
在前一节,建立了一个组件CA,其实现了IX,IY接口。在这一节,暂时把其看作是一内部组件。我们要使用其对IY接口的函数实现
新建一个DLL项目,新建一接口IX,新建一个组件的CLSID。另外,导入CA项目IFACE.h中的IY接口IID和CA组件的CLSID。如下所示:
extern "C"
{
// {3CA3B6D4-799C-4d5d-BF3A-373C4EECE925} 此IX是新建的IID
static const IID IID_IX =
{ 0x3ca3b6d4, 0x799c, 0x4d5d,
{ 0xbf, 0x3a, 0x37, 0x3c, 0x4e, 0xec, 0xe9, 0x25 } };
// {41A5F090-B33A-4ae8-A1BB-EF2D0B4F8B0E} //此IY是从CA中IID_IY的复制
static const IID IID_IY =
{ 0x41a5f090, 0xb33a, 0x4ae8,
{ 0xa1, 0xbb, 0xef, 0x2d, 0xb, 0x4f, 0x8b, 0xe } };
}
// {3D29721C-8D93-4c24-A8A5-4CE01FD9FD00} 这是CB组件新建的CLSID
static const CLSID CLSID_CTANINFACE =
{ 0x3d29721c, 0x8d93, 0x4c24,
{ 0xa8, 0xa5, 0x4c, 0xe0, 0x1f, 0xd9, 0xfd, 0x0 } };
// {282D8F98-BC89-43d5-9225-0B1BB479CBDE} 这是CA组件复制过来的CLSID
static const CLSID CLSID_Component1 =
{ 0x282d8f98, 0xbc89, 0x43d5,
{ 0x92, 0x25, 0xb, 0x1b, 0xb4, 0x79, 0xcb, 0xde } };
相关文章推荐
- 包容和聚合(COM技术内幕笔记五)
- COM技术内幕学习笔记---第八章---组件复用:包容和聚合
- COM 技术内幕学习之八(包容和聚合)
- COM技术内幕--包容和聚合
- COM技术内幕第四章笔记-引用计数
- COM技术内幕中聚合的实现
- COM技术内幕第六章笔记-HRESULT、GUID、注册表及其他
- COM技术内幕学习笔记(2)
- COM组件的类厂(COM技术内幕笔记之四)
- COM技术内幕第五章笔记-动态链接
- COM技术内幕第十章笔记-EXE中的服务器
- COM技术内幕学习笔记---第七章---类厂
- 【转】COM技术内幕(笔记)
- 动态链接库实现COM(COM技术内幕笔记之二)
- com技术内幕第七章笔记-类厂
- COM技术内幕第八章笔记-组件复用
- COM技术内幕学习笔记
- COM组件的类厂(COM技术内幕笔记之四)
- COM中的HRESULT, CLISD,ProgID, DLL注册,COM库函数的知识(COM技术内幕笔记之三)
- COM程序的简单实现(COM技术内幕笔记之一)