高级软件工程07包含与聚合_第1页
高级软件工程07包含与聚合_第2页
高级软件工程07包含与聚合_第3页
高级软件工程07包含与聚合_第4页
高级软件工程07包含与聚合_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、4、包含与聚合如果一个构件B使用另外一个构件A我们称使用者B为:外部构件 被使用者A为:内部构件则:外部构件B包含(聚合)内部构件A包含与聚合是COM的两种复用方式(模型)为系统升级、扩展提供支持包含与聚合1(1)包含与聚合简介(2)包含的实现(3)聚合的实现(4)例子包含与聚合2(1)包含与聚合简介包含(Containment)对象A对象BIYIXIX包含与聚合3对象 B 的成员函数在调用对象A的接口之前或之后可以进行其他一些操作IX提供的功能可以超过IX对象B是对象A 的客户而对象B的客户看到的只是对象B显露出的接口(IY、IX)对象A的创建与释放完全在对象B内部进行对象A的生命期包含在对

2、象B的生命期内包含与聚合4对象A对象B聚合(Aggregation)IYIX包含与聚合5可以将聚合看作是包含的一个特例更好地体现了复用 虽然对象A直接向对象B的客户提供服务 但 对象B的客户感觉不到对象A的存在对象A的生存期受到对象B的控制实现聚合的关键在于 QueryInterface:当客户向对象B请求IX时对象B的QueryInterface返回对象A的IX指针存在问题: (1)从IX如何得到IY?(2)从IX得到的Iunknown如何与从IY得到的IUnknown 相同?包含与聚合6包含的复用性建立在客户/服务器模式上聚合的复用性需要内部构件提供支持复用方式的选择:当内部构件提供的接口

3、完全满足要求时使用聚合合适当内部构件提供的接口与需求类似时使用包含合适在一个对象中可以同时使用两种复用方式包含与聚合7(2)包含的实现假定IX、IY的定义分别为:class IX:public IUnknown public : virtual HRESULT _stdcall FX() =0;class IY:public IUnknown public : virtual HRESULT _stdcall FY() =0;包含与聚合8对象B的定义为:class CB: public IX, public IY protected: ULONG m_ref;public: CB(); CB(

4、); / IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/IXHRESULT _stdcall FX();/IYHRESULT _stdcall FY(); HRESULT Init();private:IX *m_pIX;包含与聚合9类B的实现: CB:CB()m_pIX = null;m_Ref = 0; CB:CB()if (m_pIX != null

5、) m_pIX-Release();HRESULT CB:Init() HRESULT result = :CoCreateInstance(CLSID_ComponentA,null, CLSCTX_INPROC_SERVER,IID_ISomeInterface,(void *)&m_pIX);if (FAILED(result) return E_FAIL;else return S_OK;HRESULT _stdcall CB:IX() return m_pIX-FX();包含与聚合10包含的主要用途:扩展接口 假定想把一个 Iairplane接口扩展为 IFloatPlane:定义:

6、interface Iairplane: Iunknownvoid Takeoff();void fly();void Land();interface IFloatPlane: Iairplane void Float();void Sink();void Rust();void DrainBankAccount();包含与聚合11(3)聚合的实现对象B的定义为:class CB: public IY protected: ULONG m_ref;public: CB(); CB(); / IUnknownvirtual HRESULT _stdcall QueryInterface(con

7、st IID& iid, void* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/IYHRESULT _stdcall FY(); HRESULT Init();private:IUnknown *m_pUnknownInner;包含与聚合12HRESULT _stdcall CB:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown)*ppv = static_cast(this) ; else if (iid =

8、IID_IY)*ppv = static_cast(this) ;else if (iid = IID_IX)return m_pUnknownInner-QueryInterface(iid,ppv);else*ppv = NULL ;return E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;包含与聚合13问题:QueryInterfaceAddRefReleaseFyQueryInterfaceAddRefReleaseFxIYIX内部构件的IUnknown实现外部构件的IUnknown实现内部构件外部构件包含与

9、聚合14解决方法:将内部构件的IUnknown接口进行隐藏使内部构件的接口调用外部接口的IUnknown接口这样,内部构件将实现两个IUnknown接口一个是“非代理未知接口”按一般方式实现IUnknown接口一个是“代理未知接口”如果内部构件未被聚合则代理未知接口将调用转发给非代理未知接口如果内部构件被聚合代理未知接口将调用转发给外部构件实现的未知接口包含与聚合15CoCreateInstance与IClassFactory中的pIUnknownOuter:HRESULT_stdcall CoCreateInstance(const CLSID& clsid,Iunkown * pIUnkn

10、ownOuter,DWORD dwClsContext,const IID& iid,void * ppv);HRESULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );包含与聚合16QueryInterfaceAddRefReleaseFxIX代理Iunknown实现非聚合构件非代理Iunknown实现包含与聚合17QueryInterfaceAddRefReleaseFyQueryInterfaceAddRefReleaseFxIYIX代理Iunknown的实现外部构件的IUnk

11、nown实现内部构件外部构件非代理Iunknown的实现包含与聚合18内部构件的创建 涉及三个函数: 外部构件的 Init 函数内部构件类厂的CreateInstance内部构件的构造函数外部构件的 Init 函数:HRESULT _stdcall CB:Init() IUnknown * pUnknownOuter = this;HRESULT hr = CoCreateInstance(CLSID_ComponentA, pIUnknownOuter,CLSCTX_INPROC_SERVER,IID_IUnknown, (void * ) &m_pUnknownInner);if (FAI

12、LED(hr) return E_FAIL;else return S_OK;包含与聚合19内部构件类厂的CreateInstance:HRESULT _stdcallCfactory:CreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv )/ To aggregate, iid must be IID_IUnknown. If (pUnknownOuter != NULL)&(iid != IID_IUnknown) return CLASS_E_NOAGGREGATION; ;/Create componen

13、t.CB *pB = new CB(pUnknownOuter); if( pB = NULL) return E_OUTOFMEMORY;HRESULT hr= pB-NondelegationQueryInterface(iid,ppv);pB-NondelegatingRelease();return hr;包含与聚合20内部构件的构造函数:CB:CB(IUnknown * pUnknownOuter):m_cRef(1) :InterlockedIncrement(&g_cComponents); if(pUnknownOuter = NULL) /Not being aggregat

14、ed, use nondelegating unknown.m_pUnknownOuter = reinterpret_cast(static_cast(this); else /Being aggregated, use outer unknown.m_pUnknownOuter = pUnknownOuter; 包含与聚合21对外部构件Init的补充HRESULT _stdcall CB:Init() IUnknown * pUnknownOuter = this;HRESULT hr = CoCreateInstance(CLSID_ComponentA, pIUnknownOuter,CLSCTX_INPROC_SERVER,IID_IUnknown, (void * ) &

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论