版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、4、包含与聚合、包含与聚合假设一个构件假设一个构件B运用另外一个构件运用另外一个构件A 我们称运用者我们称运用者B为:外部构件为:外部构件 被运用者被运用者A为:内部构件为:内部构件那么:外部构件那么:外部构件B包含聚合内部构件包含聚合内部构件A包含与聚合是包含与聚合是COM的两种复用方式模型的两种复用方式模型为系统晋级、扩展提供支持为系统晋级、扩展提供支持1包含与聚合简介包含与聚合简介2包含的实现包含的实现3聚合的实现聚合的实现4例子例子1包含与聚合简介包含与聚合简介包含Containment对象A对象BIYIXIX对象对象 B 的成员函数在调用对象的成员函数在调用对象A的接口之前或之后的接
2、口之前或之后可以进展其他一些操作可以进展其他一些操作IX提供的功能可以超越提供的功能可以超越IX对象对象B是对象是对象A 的客户的客户而对象而对象B的客户看到的只是对象的客户看到的只是对象B显显露的接口显显露的接口IY、IX对象对象A的创建与释放完全在对象的创建与释放完全在对象B内部进展内部进展对象对象A的生命期包含在对象的生命期包含在对象B的生命期内的生命期内对象A对象B聚合(Aggregation)IYIX可以将聚合看作是包含的一个特例可以将聚合看作是包含的一个特例更好地表达了复用更好地表达了复用 虽然对象虽然对象A直接向对象直接向对象B的客户提供效力的客户提供效力 但但 对象对象B的客户
3、觉得不到对象的客户觉得不到对象A的存在的存在对象对象A的生存期遭到对象的生存期遭到对象B的控制的控制实现聚合的关键在于实现聚合的关键在于 QueryInterface:当客户向对象当客户向对象B恳求恳求IX时时对象对象B的的QueryInterface前往对象前往对象A的的IX指针指针存在问题:存在问题: 1从从IX如何得到如何得到IY?2从从IX得到的得到的Iunknown如何与从如何与从IY得到的得到的IUnknown 一样?一样?包含的复用性建立在客户包含的复用性建立在客户/效力器方式上效力器方式上聚合的复用性需求内部构件提供支持聚合的复用性需求内部构件提供支持复用方式的选择:复用方式的
4、选择:当内部构件提供的接口完全满足要求时当内部构件提供的接口完全满足要求时运用聚适宜宜运用聚适宜宜当内部构件提供的接口与需求类似时当内部构件提供的接口与需求类似时运用包含适宜运用包含适宜在一个对象中可以同时运用两种复用方式在一个对象中可以同时运用两种复用方式(2)包含的实现包含的实现假定假定IX、IY的定义分别为:的定义分别为:class IX:public IUnknown public : virtual HRESULT _stdcall FX() =0;class IY:public IUnknown public : virtual HRESULT _stdcall FY() =0;对
5、象对象B的定义为:的定义为:class CB: public IX, public IY protected: ULONG m_ref;public: CB(); CB(); / 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
6、();private:IX *m_pIX;类类B的实现:的实现: CB:CB()m_pIX = null;m_Ref = 0; CB:CB()if (m_pIX != null) 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
7、_stdcall CB:IX() return m_pIX-FX();包含的主要用途:扩展接口包含的主要用途:扩展接口 假定想把一个假定想把一个 Iairplane接口扩展为接口扩展为 IFloatPlane:定义:定义:interface Iairplane: Iunknownvoid Takeoff();void fly();void Land();interface IFloatPlane: Iairplane void Float();void Sink();void Rust();void DrainBankAccount();(3)聚合的实现聚合的实现对象对象B的定义为:的定义为:
8、class CB: public IY protected: ULONG m_ref;public: CB(); CB(); / IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/IYHRESULT _stdcall FY(); HRESULT Init();private:IUnknown *m_pUnknownInner;HRESULT _stdc
9、all CB:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown)*ppv = static_cast(this) ; else if (iid = 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_
10、OK ;问题:QueryInterfaceAddRefReleaseFyQueryInterfaceAddRefReleaseFxIYIX内部构件的IUnknown实现外部构件的IUnknown实现内部构件外部构件处理方法:将内部构件的处理方法:将内部构件的IUnknown接口进展隐藏接口进展隐藏使内部构件的接口使内部构件的接口调用外部接口的调用外部接口的IUnknown接口接口这样,内部构件将实现两个这样,内部构件将实现两个IUnknown接口接口一个是一个是“非代理未知接口非代理未知接口按普通方式实现按普通方式实现IUnknown接口接口一个是一个是“代理未知接口代理未知接口假设内部构件未
11、被聚合假设内部构件未被聚合那么代理未知接口将调用那么代理未知接口将调用转发给非代理未知接口转发给非代理未知接口假设内部构件被聚合假设内部构件被聚合代理未知接口将调用代理未知接口将调用转发给外部构件实现的未知接口转发给外部构件实现的未知接口CoCreateInstance与IClassFactory中的pIUnknownOuter:HRESULT_stdcall CoCreateInstance(const CLSID& clsid,Iunkown * pIUnknownOuter,DWORD dwClsContext,const IID& iid,void * ppv);HRE
12、SULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );QueryInterfaceAddRefReleaseFxIX代理Iunknown实现非聚合构件非代理Iunknown实现QueryInterfaceAddRefReleaseFyQueryInterfaceAddRefReleaseFxIYIX代理Iunknown的实现外部构件的IUnknown实现内部构件外部构件非代理Iunknown的实现内部构件的创建内部构件的创建 涉及三个函数:涉及三个函数: 外部构件的外部构件的
13、 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 (FAILED(hr) return E_FAIL;else
14、return S_OK;内部构件类厂的内部构件类厂的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 component.CB *pB = new CB(p
15、UnknownOuter); if( pB = NULL) return E_OUTOFMEMORY;HRESULT hr= pB-NondelegationQueryInterface(iid,ppv);pB-NondelegatingRelease();return hr;内部构件的构造函数内部构件的构造函数:CB:CB(IUnknown * pUnknownOuter):m_cRef(1) :InterlockedIncrement(&g_cComponents); if(pUnknownOuter = NULL) /Not being aggregated, use nondelegating unknown.m_pUnknownOuter = reinterpret_cast(static_cast(this); else /Being aggregated, use outer unknown.m_pUnknownOuter = pUnknownOuter; 对外部构件Init的补充HRESULT _stdcall CB:Init() IUnknown * pUnknownOuter = this;HRESULT hr = CoCreateInstance(CLSID_ComponentA, pIUnknownOuter,CLSCTX_INPROC_SER
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 品质医疗专业护理我们的医疗承诺
- 硬件采购合同
- 转让协议范文
- 岁以上用工协议
- 假期工劳务协议书
- 门面房装修合同书
- 外墙保温劳务清包合同
- 干洗服务协议合同范文
- 就业三方协议书
- 合伙人退股协议书
- 智能锅炉故障诊断与预警系统设计
- 体育教育专业就业前景分析
- 2024届福建省厦门市第一中学十校联考最后数学试题含解析
- 化工原理智慧树知到课后章节答案2023年下武汉科技大学
- 20100927-宣化上人《愣严咒句偈疏解》(简体全)
- 2023年秋季国家开放大学-02447-城市轨道交通行车组织期末考试题带答案
- 硅光集成技术
- 房屋加装电梯施工项目施工组织设计方案
- 2021年化学高考真题卷-上海(含答案解析)
- 镇墩稳定计算
- 国家开放大学电大《中级财务会计(二)》2021-2022期末试题及答案(试卷代号:2608)
评论
0/150
提交评论