ATL 接口映射宏详解 (中 ) 三、COM_INTERFACE_ENTRY_TEAR_OFF(iid, x) 参考ATL 例程Beeper、 COMMAP 使用这个宏的目的就是为了把一些很少用到的接口放在一个单独的组件中实现,仅当查询到这个接口时,才创建这个组件,并且当它的引用计数减为0 时就会被释放掉。我们知道ATL 中组件是通过多重继承实现的,每继承一个接口,在为它分配的内存块中就会多一个虚函数表指针,用这个宏就可以为每个组件的实例节省下这一个虚函数表指针来(一个指针4个字节,好象也不多啊,呵呵) 下面我们来看它的典型用法: class CTearOff1: //该类是专门用来实现分割接口ITearOff1 的 public IDispatchImpl< ITearOff1, &IID_ITearOff1, &LIBID_COMMAPLib >, public CComTearOffObjectBase //外部对象 { public: CTearOff1(){} ~CTearOff1(){} BEGIN_COM_MAP(CTearOff1) COM_INTERFACE_ENTRY(ITearOff1) END_COM_MAP() HRESULT STDMETHODCALLTYPE get_Name(BSTR* pbstrName) { *pbstrName = ::SysAllocString(L"ITearOff1"); return S_OK; } }; class COuter : public ..... //我们真正要实现的组件 { public: ........... BEGIN_COM_MAP(COuter) ........... COM_INTERFACE_ENTRY_TEAR_OFF(IID_ITearOff1, CTearOff1) END_COM_MAP() ........... }; CTearOff1 实现了Tear-off 接口ITearOff1,实现方法与其他组件并无不同。唯一不同的是它从CComTearOffObjectBase 继承,CComTearOffObjectBase 定义如下: template < class Owner, class ThreadModel = CComObjectThreadModel > class CComTearOffObjectBase : public CComObjectRootEx { public: typedef Owner _OwnerClass; CComObject* m_pOwner; CComTearOffObjectBase() {m_pOwner = NULL;} }; 我们又看到了我们熟悉的一个类CComObject, 它是组件的真正生成类。从上面的定义中可知道 CComTearOffObjectBase 主要功能就是包含了一个指向外部对象(在这里就是我们的组件类 CComObject)的指针。它的功能将在后面看到。 我们继续用我们的老办法来跟踪一下看看它的执行过程。假设pOuter 是我们已经获得的组件的 IOuter 接口指针。 执行pOuter->QueryInterface(IID_ITearOff1, (void **)&pTear1); 函数堆栈一: 7.CTearOff1::_InternalQueryInterface(...) 6.ATL::CComInternalCreator< ATL::CComTearOf...