COM技术内幕--包容和聚合

包容简介:
一个包含有一个内部组件并使用了其IZ接口的外部组件的内部结构
//


在COM中,同其他内容类似,包容也是在接口级完成的。
一个包含有一个内部组件并复用了其IY接口实现的外部组件的内部结构
///

当外部组件聚合某个接口时,它将把接口指针直接传给客户,而并不角包容那样重新实现此接口并将函数调用转发给内部组件。
//

聚合简介:
聚合是包容的一个特例。当一个外部组件聚合了某个内部组件的一个接口时,它并没有像包容那样重新实现此接口并明确地将调用请求转发给内部组件。
相反,外部组件将直接把内部组件的接口指针返回给客户。使用此种方法,外部组件将无需重新实现并转发接口中的所有函数。

包容和聚合的比较:
对于聚合的每一个接口,可能会包容成百上千的其他接口。这是因为当组件作为客户去使用其他组件的接口时,实际就可以看成是一种包容。
聚合则更为特殊。当某个组件已经实现了我们待实现的某个接口时,就可以使用聚合,即将此组件的接口指针传给客户。

包容的实现:

class CA:public IX,public IY
{
public:
virtual HRESULT __stdcall QueryInterface(const IID&iid,void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
// Interface IX
virtual void __stdcall Fx(){cout<<"Fx"<<endl;}
// Interface IY
virtual void __stdcall Fy(){m_pIY->Fy();}
// Constructor
CA();
// Destructor
~CA();
HRESULT Init();
private:
long m_cRef;
IY* m_pIY;
};

CA::CA():m_cRef(1),m_pIY(NULL)
{
InterlockedIncrement(&g_oComponents);
}

CA::~CA()
{
InterlockedDecrement(&g_oComponents);
trace("Destroy self.");
if (m_pIY != NULL)
{
m_pIY->Release();
}
}

HRESULT CA::Init()
{
trace("Create Contained component.");
HRESULT hr = ::CoCreateInstance(CLSID_Component2,
NULL,
CLSCTX_INPROC_SERVER,
IID_IY,
(void**)&m_pIY);
if (FAILED(hr))
{
trace("Could not create contained component.");
return E_FAIL;
}
else
{
return S_OK;
}
}

// CreateInstance Fucntion
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID&iid,
void** ppv)
{
if (pUnknownOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
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;
}
聚合的实现:
在c++中并没有同聚合等价的特性。聚合实际上是继承性的一个动态形式,而c++的继承则总是静态的。在c++中模拟聚合的最好的方法是重载->操作符。但重载 ->操作符同COM聚合相比仍有许多限制。例如它只能将调用请求转发给某一个类,而在COM中则可以聚合任意数目的接口。


class CA:public IX
{
public:
virtual HRESULT __stdcall QueryInterface(const IID&iid,void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
// Interface IX
virtual void __stdcall Fx(){cout<<"Fx"<<endl;}
// Constructor
CA();
// Destructor
~CA();
HRESULT Init();
private:
long m_cRef;
IUnknown* m_pInnerUnknown;
};

HRESULT __stdcall CA::QueryInterface(const IID&iid,
void** ppv)
{
if (iid==IID_IUnknown)
{
*ppv = static_cast<IX*>(this);
}
else if (iid==IID_IX)
{
*ppv = static_cast<IX*>(this);
}
else if (iid==IID_IY)
{
return m_pInnerUnknown->QueryInterface(iid,ppv)
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值