国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

COM---組件復(fù)用:包容與聚合

2019-11-08 18:35:17
字體:
供稿:網(wǎng)友

包容和 聚合為實(shí)現(xiàn)組件復(fù)用和定制提供了一種極魯棒性的機(jī)制。使得COM框架下不需要實(shí)現(xiàn)繼承,客戶通組件的實(shí)現(xiàn)完全隔離開。 如果希望給組件增加新的接口,可以使用聚合。聚合是包容的一個(gè)特例。

以下代碼只列出了關(guān)鍵部分,其它部分省略。

包容

外部組件包含指向內(nèi)部組件接口的指針,此時(shí)外部組件只是內(nèi)部組件的一個(gè)客戶。外部組件可通過將調(diào)用轉(zhuǎn)發(fā)給內(nèi)部組件來重新實(shí)現(xiàn)內(nèi)部組件的某個(gè)接口,還可在內(nèi)部組件代碼前后加上一些代碼對(duì)接口改造。

組件1中的新成員m_pIY保存了指向所包容的組件2中IY接口的指針

外部組件

//// Component A//class CA : public IX, public IY //@N{public: // IUnknown 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() ;} //@N // Constructor CA() ; // Destructor ~CA() ; // Initialization function called by the class factory // to create the contained component HRESULT __stdcall Init() ; //@NPRivate: // Reference count long m_cRef ; // 被包容的組件 IY* m_pIY ;} ;//// Constructor//CA::CA(): m_cRef(1), m_pIY(NULL) //@N 內(nèi)部組件初始化{ ::InterlockedIncrement(&g_cComponents) ;}//// Destructor//CA::~CA() { ::InterlockedDecrement(&g_cComponents) ; trace("Destroy self.") ; // 釋放內(nèi)部組件 @N if (m_pIY != NULL) { m_pIY->Release() ; }}// 創(chuàng)建內(nèi)部組件HRESULT __stdcall CA::Init(){ trace("Create contained component.") ; //外部組件請(qǐng)求了內(nèi)部組件IY接口的指針,若調(diào)用成功,被保存在m_pIY中 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 ; }}

外部組件的類廠

//// IClassFactory implementation//HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) { // Cannot aggregate if (pUnknownOuter != NULL) { return CLASS_E_NOAGGREGATION ; } // 創(chuàng)建外部組件 CA* pA = new CA ; if (pA == NULL) { return E_OUTOFMEMORY ; } // 創(chuàng)建內(nèi)部組件 @N HRESULT hr = pA->Init() ; if (FAILED(hr)) { // 如何失敗,則刪除 pA->Release() ; return hr ; } // Get the requested interface. hr = pA->QueryInterface(iid, ppv) ; pA->Release() ; return hr ; }

聚合

為了實(shí)現(xiàn) 聚合,內(nèi)部組件需要實(shí)現(xiàn)兩個(gè)不同的接口,其中一個(gè)是非代理IUknown接口:按通常的方式實(shí)現(xiàn)內(nèi)部組件的IUknown接口。另一個(gè)是代理接口:未被聚合時(shí)將函數(shù)調(diào)用轉(zhuǎn)發(fā)給非代理接口,被聚合時(shí)轉(zhuǎn)發(fā)給外部組件的IUknown接口。

聚合情況下,代理IUknown接口將調(diào)用外部組件的IUknown實(shí)現(xiàn)。外部組件也可以內(nèi)部組件的非代理IUknown接口來控制組件的生命期。

外部組件

//// Component A//class CA : public IX // public IY @N{public: // IUnknown 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 ;} /* @N Component1 aggregates instead of implementing interface IY. // Interface IY virtual void __stdcall Fy() { m_pIY->Fy() ;} */ // Constructor CA() ; // Destructor ~CA() ; // Initialization function called by the class factory // to create the contained component HRESULT __stdcall Init() ; // @Nprivate: // Reference count long m_cRef ; // Pointer to the aggregated component's IY interface // (We do not have to retain an IY pointer. However, we // can use it in QueryInterface.) IY* m_pIY ; // @N // Pointer to inner component's IUnknown IUnknown* m_pUnknownInner ; // @N} ;//// Destructor// 在外部組件的析構(gòu)中釋放內(nèi)部組件接口CA::~CA() { ::InterlockedDecrement(&g_cComponents) ; trace("Destroy self.") ; // 恢復(fù)引用計(jì)數(shù),保證組件不會(huì)試圖再次將自己釋放掉 m_cRef = 1 ; // 因?yàn)閷?duì)內(nèi)部組件的Release將會(huì)導(dǎo)致對(duì)外部組件的Release調(diào)用 IUnknown* pUnknownOuter = this ; pUnknownOuter->AddRef() ; // 將外部組件釋放掉 m_pIY->Release() ; // 將內(nèi)部組件釋放掉 if (m_pUnknownInner != NULL) // @N { m_pUnknownInner->Release() ; }}// 創(chuàng)建內(nèi)部組件HRESULT __stdcall CA::Init(){ // Get the pointer to the outer unknown. // Since this component is not aggregated, the outer unknown // is the same as the this pointer. IUnknown* pUnknownOuter = this ; trace("Create inner component.") ; HRESULT hr = ::CoCreateInstance(CLSID_Component2, pUnknownOuter, // 外部組件IUnknown接口 @N CLSCTX_INPROC_SERVER, IID_IUnknown, // IUnknown,當(dāng)聚合時(shí) @N (void**)&m_pUnknownInner) ; if (FAILED(hr)) { trace("Could not create contained component.") ; return E_FAIL ; } //需要在創(chuàng)建了內(nèi)部組件之后再請(qǐng)求其IID_IY接口 //QueryInterface會(huì)調(diào)用AddRef,由于內(nèi)部組件是被聚合的,會(huì)被轉(zhuǎn)發(fā)給外部組件的AddRef //因此,會(huì)導(dǎo)致外部組件的引用計(jì)數(shù)增加,而內(nèi)部組件引用計(jì)數(shù)不變 trace("Get the IY interface from the inner component.") ; hr = m_pUnknownInner->QueryInterface(IID_IY, (void**)&m_pIY) ; //@N if (FAILED(hr)) { trace("Inner component does not support interface IY.") ; m_pUnknownInner->Release() ; return E_FAIL ; } // 為了實(shí)現(xiàn)正確計(jì)數(shù),因?yàn)閯?chuàng)建內(nèi)部組件會(huì)導(dǎo)致外部組件計(jì)數(shù)增大 pUnknownOuter->Release() ; //@N return S_OK ;}//// IUnknown implementation//HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv){ if (iid == IID_IUnknown) { *ppv = static_cast<IUnknown*>(this) ; } else if (iid == IID_IX) { *ppv = static_cast<IX*>(this) ; } else if (iid == IID_IY) { trace("Return inner component's IY interface.") ;#if 1 // 得到指向內(nèi)部接口的指針 return m_pUnknownInner->QueryInterface(iid,ppv) ; //@N#else // Or you can return a cached pointer. *ppv = m_pIY ; //@N // Fall through so it will get AddRef'ed#endif } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; return S_OK ;}

外部組件的類廠

//// IClassFactory implementation//HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) { // Cannot aggregate if (pUnknownOuter != NULL) { return CLASS_E_NOAGGREGATION ; } // Create component. CA* pA = new CA ; if (pA == NULL) { return E_OUTOFMEMORY ; } // Initialize the component. @N HRESULT hr = pA->Init() ; if (FAILED(hr)) { // Initialization failed. Delete component. pA->Release() ; return hr ; } // Get the requested interface. hr = pA->QueryInterface(iid, ppv) ; pA->Release() ; return hr ; }

內(nèi)部組件需要實(shí)現(xiàn)的接口—非代理IUknown接口

//// 非代理 IUnknown 接口 @N//struct INondelegatingUnknown{ virtual HRESULT __stdcall NondelegatingQueryInterface(const IID&, void**) = 0 ; virtual ULONG __stdcall NondelegatingAddRef() = 0 ; virtual ULONG __stdcall NondelegatingRelease() = 0 ;} ;//// IUnknown implementation//HRESULT __stdcall CB::NondelegatingQueryInterface(const IID& iid, void** ppv){ if (iid == IID_IUnknown) { //將this指針換成了INondelegatingUnknown指針,重要! //保證返回的是一個(gè)非代理IUknown指針 //當(dāng)非代理接口指針查詢IID_IUknown接口時(shí),返回的將總是一個(gè)指向 //其自身的指針。若不進(jìn)行轉(zhuǎn)換,返回的將是指向代理IUknown接口的指針 *ppv = static_cast<INondelegatingUnknown*>(this) ; // @N } else if (iid == IID_IY) { *ppv = static_cast<IY*>(this) ; } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; return S_OK ;}

內(nèi)部組件

//// Component //class CB : public IY, public INondelegatingUnknown{public: // 代理 IUnknown // 以內(nèi)聯(lián)方式實(shí)現(xiàn) // 只要將調(diào)用請(qǐng)求轉(zhuǎn)發(fā)給外部IUknown接口或非代理IUnknown接口即可 virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) { trace("Delegate QueryInterface.") ; return m_pUnknownOuter->QueryInterface(iid, ppv) ; } virtual ULONG __stdcall AddRef() { trace("Delegate AddRef.") ; return m_pUnknownOuter->AddRef() ; } virtual ULONG __stdcall Release() { trace("Delegate Release.") ; return m_pUnknownOuter->Release() ; } // 非代理 IUnknown virtual HRESULT __stdcall NondelegatingQueryInterface(const IID& iid, void** ppv) ; virtual ULONG __stdcall NondelegatingAddRef() ; virtual ULONG __stdcall NondelegatingRelease() ; // Interface IY virtual void __stdcall Fy() { cout << "Fy" << endl ;} // Constructor CB(IUnknown* m_pUnknownOuter) ; // Destructor ~CB() ;private: long m_cRef ; //引用計(jì)數(shù) //當(dāng)此組件被聚合時(shí),指向外部IUknown接口 IUnknown* m_pUnknownOuter ;} ;//// Constructor// 將外部IUknown的指針傳給內(nèi)部組件的構(gòu)造函數(shù),初始化m_pUnknownOuterCB::CB(IUnknown* pUnknownOuter) : m_cRef(1){ ::InterlockedIncrement(&g_cComponents) ; //若此組件未被聚合,將m_pUnknownOuter設(shè)為指向非代理IUknown接口 if (pUnknownOuter == NULL) { trace("Not aggregating; delegate to nondelegating IUnknown.") ; m_pUnknownOuter = reinterpret_cast<IUnknown*> (static_cast<INondelegatingUnknown*> (this)) ; } //若此組件被聚合,指向外部IUKnown接口 else { trace("Aggregating; delegate to outer IUnknown.") ; m_pUnknownOuter = pUnknownOuter ; }}

內(nèi)部組件的類廠

//// IClassFactory implementation//HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv){ //當(dāng)pUnknownOuter非空,表示外部組件想進(jìn)行聚合 //iid必須為IID_IUnknown,因?yàn)楫?dāng)組件被聚合時(shí),只能返回一個(gè)IUknown接口 if ((pUnknownOuter != NULL) && (iid != IID_IUnknown)) //@N { return CLASS_E_NOAGGREGATION ; } // Create component. CB* pB = new CB(pUnknownOuter) ; // @N if (pB == NULL) { return E_OUTOFMEMORY ; } //獲取新創(chuàng)建的內(nèi)部組件中客戶所請(qǐng)求的接口 //并非調(diào)用QueryInterface //因?yàn)轭悘S需要返回一個(gè)指向非代理IUknown接口的指針 HRESULT hr = pB->NondelegatingQueryInterface(iid, ppv) ; //@N pB->NondelegatingRelease() ; return hr ; }

客戶

//// Client.cpp - client implementation//#include <iostream.h>#include <objbase.h>#include "Iface.h"void trace(const char* msg) { cout << "Client: /t" << msg << endl ;}//// main function//int main(){ // Initialize COM Library CoInitialize(NULL) ; trace("Get interface IX from Component 1.") ; IX* pIX = NULL ; HRESULT hr = ::CoCreateInstance(CLSID_Component1, NULL, CLSCTX_INPROC_SERVER, IID_IX, (void**)&pIX) ; if (SUCCEEDED(hr)) { trace("Succeeded creating component.") ; pIX->Fx() ; trace("Get interface IY from IX.") ; IY* pIY = NULL ; hr = pIX->QueryInterface(IID_IY, (void**)&pIY) ; if (SUCCEEDED(hr)) { trace("Succeeded getting interface IY from IX.") ; pIY->Fy() ; trace("Get interface IX from IY.") ; IX* pIX2 = NULL ; hr = pIY->QueryInterface(IID_IX, (void**)&pIX2); if (SUCCEEDED(hr)) { trace("Succeeded getting interface IX from IY.") ; pIX2->Release() ; } else { trace("Error! Should have gotten interface IX.") ; } pIY->Release() ; } else { trace("Could not get interface IY.") ; } pIX->Release() ; } else { cout << "Could not create component: " << hex << hr << endl ; } // Uninitialize COM Library CoUninitialize() ; return 0 ;}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 伊金霍洛旗| 乐清市| 贵德县| 墨江| 凤台县| 弋阳县| 长岭县| 同德县| 芮城县| 松潘县| 米泉市| 乌恰县| 灵台县| 夏邑县| 柞水县| 洮南市| 安丘市| 屯门区| 鸡西市| 岑溪市| 衡水市| 大安市| 苍南县| 双桥区| 阿勒泰市| 灵山县| 梁河县| 乌拉特中旗| 长治市| 闽侯县| 石渠县| 胶州市| 涿鹿县| 连江县| 禄丰县| 铜陵市| 临清市| 香港 | 徐闻县| 普洱| 沁水县|