com组件聚合

组件的聚合指的是直接将内部组件的接口暴露给外部客户,不需要外部组件进行调用转发,组件聚合的例子如下:

//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;

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值