ATL中的 CComCreator 代替new 来创建组建实例。
template <class T1>
class CComCreator {
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid,
LPVOID* ppv) {
ATLASSERT(ppv != NULL);
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
T1* p = NULL;
ATLTRY(p = new T1(pv))
if (p != NULL) {
p-> SetVoid(pv);
p-> InternalFinalConstructAddRef();
hRes = p-> _AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p-> FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p-> _AtlFinalConstruct();
p-> InternalFinalConstructRelease();
if (hRes == S_OK)
hRes = p-> QueryInterface(riid, ppv);
if (hRes != S_OK)
delete p;
}
return hRes;
}
};
由上面可以看出CComCreator中的CreateInstance实现了多步骤构造
1。new
2。SetVoid(pv) -- 在创建类厂实例时传递组建实例创建函数指针(其实就是组件中的_CreatorClass::CreateInstance)
3。FinalConstruct -- 在实现组建包容或聚合时创建内部组件
4。QueryInterface --获得组件的接口指针
由此可见,CComCreator不仅实现了new,而且同时考虑到 standalone or aggregated 等多种组建创建的需求。
而且,使用起来也必new简单。
例如:
STDMETHODIMP CAviary::CreatePenguin(IBird** ppbird) {
typedef CComCreator < CComObject <CPenguin> > PenguinCreator;
return PenguinCreator::CreateInstance(0, IID_IBird, (void**)ppbird);
}
为了实现组建创建实现的通用性,ATL将其放在了CComCoClass中。
要实现可创建的组件,必须继承CComCoClass类。
class CPenguin : ...,
public CComCoClass <CPenguin, &CLSID_Penguin> , ... {...};
其中的DECLARE_AGGREGATABLE(T)定义:
#define DECLARE_AGGREGATABLE(x) public:/
typedef ATL::CComCreator2 < ATL::CComCreator < ATL::CComObject < x > > , ATL::CComCreator < ATL::CComAggObject < x > > > _CreatorClass;
其中的_CreatorClass就用于组件实例的创建。
其中的DECLARE_CLASSFACTORY()定义:
#define DECLARE_CLASSFACTORY() DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory)
#define DECLARE_CLASSFACTORY_EX(cf)
typedef ATL::CComCreator < ATL::CComObjectCached < cf > > _ClassFactoryCreatorClass;
其中的_ClassFactoryCreatorClass就用于组件类厂的创建。
也就是说组件类厂和实例的创建都用到了CComCreator。
而其CreateInstance的过程是一样的,唯一的不同就是:CreateInstance参数pv不同。
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) {
...
}
对于类厂:pv --为组件实例创建函数指针。
对于组件:pv --为NULL。
从_ClassFactoryCreatorClass定义可以看出,对于不同组件_ClassFactoryCreatorClass是一样的.不同的的地方在于CreateInstance参数pv不同。也就是对不同组件,创建类厂时,传递不同的组件实例创建函数指针.