组件的聚合指的是直接将内部组件的接口暴露给外部客户,不需要外部组件进行调用转发,组件聚合的例子如下:
//interface IUnknown
struct IUnKnown{
virtual HRESULT QueryInterface(const IID& iid, void ** ppv) = 0;
virtual ULONG AddRef() = 0;
virtual ULONG Release() = 0;
virtual HRESULT QueryInterfaceNonAddRef(const IID& iid,void** ppv) = 0;
};
//interface IX, assume iid is IID_IX
struct IX :public IUnKnown{
virtual void Fx()=0;
};
//interface IY, assume iid is IID_IY
struct IY:public IUnKnown{
virtual void Fy() = 0;
};
//被聚合component
struct CB:public IY
{
//被聚合组件将调用转发
HRESULT QueryInterface(const IID& iid, void** pv)
{
if(NULL != m_pUnKnownOut)
return m_pUnKnownOut->QueryInterface(iid, pv);
else
{
if(iid == IID_IUnknown)
*ppv = static_cast<IY*>(this);
else if(iid == IID_IY)
//component1组件的客户请求IID_IY组件时,返回component1的IY接口
*ppv = static_cast<IY*>(this);
else if(iid == IID_CA)
*ppv = static_cast<CA*>(this);
else
{
*ppv = 0;
return 0;
}
AddRef();
return 1;
}
}
ULONG AddRef()//将生命周期控制交由外部组件
{
if(NULL != m_pUnKnownOut)
return m_pUnKnownOut->AddRef();
else
return ++m_refcnt;
}
ULONG Release()//将生命周期控制交由外部组件
{
if(NULL != m_pUnKnownOut)
return m_pUnKnownOut->Release();
else
{
--m_refcnt;
if(0 == m_refcnt)
delete this;
}
}
//仅用于外部组件,返回本内部组件的接口
HRESULT QueryInterfaceNonAddRef(const IID& iid,void** ppv)
{
if(iid == IID_IUnknown)
*ppv = static_cast<IY*>(this);
else if(iid == IID_IY)
//component1组件的客户请求IID_IY组件时,返回component1的IY接口
*ppv = static_cast<IY*>(this);
else if(iid == IID_CA)
*ppv = static_cast<CA*>(this);
else
{
*ppv = 0;
return 0;
}
return 1;
}
void Fy(){::std::cout<< "fy"<<::std::endl;}
CB():m_refcnt(0),m_pUnKnownOut(NULL){}
CB(IUnKnown* pOut):m_refcnt(0),m_pUnKnownOut(pOut){}
virtual ~CB(){}
private:
int m_refcnt;
//代理IUnKnown指针,可能转发给外部组件IUnKnown或者内部IUnKnownNounInterface
IUnKnown* m_pUnKnownOut;
};
//外部component
struct CA:public IX
{
HRESULT QueryInterface(const IID& iid, void** pv)
{
if(iid == IID_IUNKNOWN)
{
*pv = static_cast<IX*>(this);
}
else if(iid == IID_IX)
{
*pv = static_cast<IX*>(this);
}
else if(iid == IID_CA)
{
*pv = static_cast<CA*>(this);
}
else if(iid == IID_IY)
{
if(NULL != m_pInnerUnKnown)
{
//使用内部组件的非代理IUnKnown接口返回对应的IY接口
HRESULT hr = m_pInnerUnKnown->QueryInterfaceNoAddRef(iid,pv);
if(SUCCEED(hr))
static_cast<IUnKnown*>(this)->AddRef();
return hr;
}
else
{
*pv = NULL;
return E_FAIL;
}
}
else
{
*pv = NULL;
return E_FAIL;
}
static_cast<IUnKnown*>(this)->AddRef();
return S_OK;
}
ULONG AddRef()
{
++m_refcnt;
}
ULONG Release()
{
if(0 == --m_refcnt)
{
delete this;
}
return m_refcnt;
}
void Fx(){::std::cout<< "FX"<<::std::endl;}
CA():m_refcnt(0),m_pInnerUnKnown(NULL){};
~CA()
{
if(NULL != m_pInnerUnKnown)
{
delete m_pInnerUnKnown;
m_pInnerUnKnown = NULL;
}
};
HRESULT Init()
{
m_pInnerUnKnown = new CB;
}
private:
int m_refcnt;
//被聚合组件的非代理IUnKnown接口
IUnKnown* m_pInnerUnKnown;
};