包容和聚合:
包容和聚合实际上是使一个组件使用另外一个组件的一种技术。在包容的情况下,外部组件将包含内部组件。在聚合的情况下,外部组件聚合内部组件。
在此设想一下,外部组件是我们的要实现的组件,而内部组件是其它要重用的组件。
包容是外部组件包含指向内部组件接口的指针.外部组件相对来说是内部组件的一个客户,它将使用内部组件的接口来实现它自己的接口.
聚合是包容的一个特例,当一个外部组件聚合了某个内部组件的一个接口时,它并没有像包容那样重新实现此接口并明确地将调用请求转发给内部组件。相反,外部组件将直接把内部件的接口指针返回给客户。
在组件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)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
CA* pA = new CA();
if(pA == NULL)
return E_OUTOFMEMORY;
![](/Images/OutliningIndicators/InBlock.gif)
HRESULT hr = pA->Init();
if(FAILED(hr))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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
"
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
// {3CA3B6D4-799C-4d5d-BF3A-373C4EECE925} 此IX是新建的IID
static const IID IID_IX =
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ 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 =
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ 0x41a5f090, 0xb33a, 0x4ae8,
{ 0xa1, 0xbb, 0xef, 0x2d, 0xb, 0x4f, 0x8b, 0xe } };
}
//
{3D29721C-8D93-4c24-A8A5-4CE01FD9FD00} 这是CB组件新建的CLSID
static
const
CLSID CLSID_CTANINFACE
=
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{ 0x3d29721c, 0x8d93, 0x4c24,
{ 0xa8, 0xa5, 0x4c, 0xe0, 0x1f, 0xd9, 0xfd, 0x0 } }
;
![](/Images/OutliningIndicators/None.gif)
//
{282D8F98-BC89-43d5-9225-0B1BB479CBDE} 这是CA组件复制过来的CLSID
static
const
CLSID CLSID_Component1
=
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{ 0x282d8f98, 0xbc89, 0x43d5,
{ 0x92, 0x25, 0xb, 0x1b, 0xb4, 0x79, 0xcb, 0xde } }
;