WEB开发网
开发学院软件开发VC 用ATL建立轻量级的COM对象(6) 阅读

用ATL建立轻量级的COM对象(6)

 2006-07-21 11:44:26 来源:WEB开发网   
核心提示:第一部分:为什么要使用ATL,第二部分:起步篇,用ATL建立轻量级的COM对象(6),第三部分:实现IUnknown,第四部分:实现接口,另外,因为不需要为抽象基类分配vtable,第五部分:不要过分抽象,输出你的类实现了 CComObject

第一部分:为什么要使用ATL。

第二部分:起步篇。

第三部分:实现IUnknown。

第四部分:实现接口。

第五部分:不要过分抽象。

输出你的类

实现了 CComObject ,你就有足够的条件用 C++ new 操作符创建 COM 对象。不过这样做没有什么实用价值,因为毕竟外部客户端使用 CoCreateInstance 或 CoGetClassObject 创建类实例。也就是说,你必须为每个外部类输出类对象。幸运的是ATL分别在它的 CComClassFactory 和 CComClassFactory2 类中提供了缺省的 IClassFactory 和 IClassFactory2接口实现。

CComClassFactory 不是模板驱动类,但其中有一个函数指针作为数据成员,使用这个函数可以创建对象。ATL提供了一个类模板家族,它们都有一个单独的静态方法 CreateInstance,由 Creators 调用,Creators 提供正确的语义来从 CComClassFactory 创建基于 CComObjectRoot 的对象。下面的这段代码展示了缺省的创建机制:CComCreator,它产生一个模板化的类实例,并用 ATL 中标准的 FinalConstruct 来顺序初始化对象。

ATL Creator
template class CComCreator {
public:
   static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) {
         HRESULT hRes = E_OUTOFMEMORY;
         T1* p = NULL;
         ATLTRY(p = new T1(pv))
         if (p != NULL) {
             p->SetVoid(pv);
             p->InternalFinalConstructAddRef();
             hRes = p->FinalConstruct();
             p->InternalFinalConstructRelease();
             if (hRes == S_OK)
                 hRes = p->QueryInterface(riid, ppv);
             if (hRes != S_OK)
                 delete p;
         }
         return hRes;
     }
};
template class CComFailCreator {
public:
     static HRESULT WINAPI CreateInstance(void*, REFIID,
                       LPVOID*)
   { return hr; }
};
template class CComCreator2 {
public:
     static HRESULT WINAPI CreateInstance(void* pv, REFIID riid,
                       LPVOID* ppv) {
         HRESULT hRes = E_OUTOFMEMORY;
         if (pv == NULL)
             hRes = T1::CreateInstance(NULL, riid, ppv);
         else
             hRes = T2::CreateInstance(pv, riid, ppv);
         return hRes;
     }
};  
   
  因为 ATL 利用 Visual C++ 中的__declspec(novtable) 优化,所以在很大程度上依赖两层构造。declspec 取消掉了在抽象基类的构造函数中必须对 vptr 进行的初始化,因为抽象基类中的任何的 vptr 会在派生类中被重写。之所以要进行这种优化,是因为初始化从未被使用过的 vptr 毫无意义。另外,因为不需要为抽象基类分配vtable,从而减少了代码的大小。

1 2 3  下一页

Tags:ATL 建立 轻量级

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接