(60分)com聚合技术问题讨论
聚合技术问题讨论两个com对象A和B,A被B聚合。当然A也可以不被聚合,所以 与A相关有了2个接口,一个非委托,一个委托非委托接口: INondelegatingUnknown委托接口:ISomeInterfaceclass CA : public ISomeInterface, public INondelegatingUnknown{protected: ULONG m_Ref;public: CA(IUnknown *pUnknownOuter); ~CA();public : // Delegating IUnknown virtual HRESULT __stdcall QueryInterface(const IID& iid, void **ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; // Nondelegating IUnknown virtual HRESULT __stdcall NondelegationQueryInterface(const IID& iid, void **ppv); virtual ULONG __stdcall NondelegatingAddRef(); virtual ULONG __stdcall NondelegationRelease(); virtual HRESULT __stdcall SomeFunction( ) ; private : IUnknown *m_pUnknownOuter; // pointer to outer IUnknown};所以我们需要实现6个接口,这样才能给其他人或者自己继续开发.其中的一个函数:QueryInterface的实现,我有疑问:CA::QueryInterface 是一个查询接口的函数, 其大致流程为:1.如果为聚合指针不为空,则进行使用聚合对象查询2.如果聚合指针为空,则进行非委托查询NondelegationQueryInteface代码为:HRESULT CA::QueryInterface(const IID& iid, void **ppv){ if ( m_pUnknownOuter != NULL ) return m_pUnknownOuter->QueryInterface(iid, ppv); //实际上会被聚合对象B调用!!! else return NondelegationQueryInterface(iid, ppv); //非委托查询}问题出来了: 非委托查询函数,何苦 分2种情形? 看代码:(class CA:public INondelegatingUnknown,ISomeInterface)HRESULT CA::NondelegationQueryInterface(const IID& iid, void **ppv){ if ( iid == IID_IUnknown ) { *ppv = (INondelegatingUnknown *) this ; ((IUnknown *)(*ppv))->AddRef() ; //1种 } else if ( iid == IID_SomeInterface ) { *ppv = (ISomeInterface *) this ; ((ISomeInterface *)(*ppv))->AddRef() ; //2种 } else { *ppv = NULL; return E_NOINTERFACE ; } return S_OK;}何苦非两种?3. 工厂类中的 中的m_ref到底有什么用?为什么在DllGetClassObject 中创建工厂对象后, 立即查询接口,殊不知查询接口的代码很奇怪?(为什么说其诡异, 原因是:尽管你有了工厂对象,但是 你没有创建com对象A啊, 增加次数m_ref有什么用呢?)extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid, const IID& iid, void **ppv){ if (clsid == CLSID_CompA) { CAFactory *pFactory = new CAFactory; //只有工厂对象,没有com对象!!! if (pFactory == NULL) { return E_OUTOFMEMORY ; } HRESULT result = pFactory->QueryInterface(iid, ppv); //开始查询接口,都没有com对象,查了作甚? return result; } else { return CLASS_E_CLASSNOTAVAILABLE; }}class CAFactory : public IClassFactory{ protected: ULONG m_Ref; //look here ..................... //IUnknown members HRESULT __stdcall QueryInterface(const IID& iid, void **ppv); ULONG __stdcall AddRef(); ULONG __stdcall Release();};以下是CAFactory::QueryInterface的代码:HRESULT CAFactory::QueryInterface(const IID& iid, void **ppv){ if ( iid == IID_IUnknown ) { *ppv = (IUnknown *) this ; ((IUnknown *)(*ppv))->AddRef() ; //增加了m_ref的次数,有什么用呢?无用啊 } else if ( iid == IID_IClassFactory) { *ppv = (IClassFactory *) this ; ((IClassFactory *)(*ppv))->AddRef() ; //同理这里也是 } else { *ppv = NULL; return E_NOINTERFACE ; } return S_OK;}