一边情况下,COM组件会是这样。
class ATL_NO_VTABLE CMath :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMath, &CLSID_Math>,
public IMath,
public IAdvancedMath
{
...
}
CMath是由用户定义,但它其实是一个抽象类,即必须有个类继承自CMath。这给类默认是CCOMObject<CMath>。它提供了IUnknow的三个接口,AddRef(),Release(),QueryInterface()。
之所以使用模板,是为了不使用虚指针,但实现了多态的功能。
CMath继承自CComCoClass,它封装了一系列关于注册表注册、得到类厂接口等工作。
看一下CComCoClass的定义。
template <class T, const CLSID* pclsid = &CLSID_NULL>
class CComCoClass
{
public:
DECLARE_CLASSFACTORY()
DECLARE_AGGREGATABLE(T)
typedef T _CoClass;
...
}
DECLARE_CLASSFACTORY的定义。
#define DECLARE_CLASSFACTORY() \
typedef CComCreator< CComObjectCached< CComClassFactory > > _ClassFactoryCreatorClass;
DECLARE_AGGREGATABLE的定义。
#define DECLARE_AGGREGATABLE(x) public:\
typedef CComCreator2< CComCreator< CComObject< x > >, CComCreator< CComAggObject< x > > > _CreatorClass;
_ClassFactoryCreatorClass和_CreatorClass这两个typedef,用于
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Math, CMath)
END_OBJECT_MAP()
这几个宏产生一个表。表中的元素元素为CLSID_Math, CMath::_ClassFactoryCreatorClass::CreateInstance,CMath::_CreatorClass::CreateInstance,等等。
CMath::_ClassFactoryCreatorClass::CreateInstance对应着产生类厂接口的方法。
CMath::_CreatorClass::CreateInstance对应着产生类中某个接口的方法。
使用方法如:
IClassFactory *pFC = NULL;
CMath::_ClassFactoryCreatorClass::CreateInstance(NULL,IID_IClassFactory,(void**)&pFC);
IAdvancedMath *p = NULL;
CMath::_CreatorClass::CreateInstance(NULL,IID_IAdvancedMath,(void**)&p);
回头看一眼_ClassFactoryCreatorClass的定义。
typedef CComCreator< CComObjectCached< CComClassFactory > > _ClassFactoryCreatorClass;
CComObjectCached< CComClassFactory >继承自CComClassFactory。CComObjectCached的功能类似于CCOMObject。不同之处在于有个cache机制,正好用于类厂。
CComCreator提供一个CComObjectCached< CComClassFactory >的CreateInstance方法。
回头看一眼_CreatorClass的定义。
typedef CComCreator2< CComCreator< CComObject< x > >, CComCreator< CComAggObject< x > > > _CreatorClass;
CComCreator2用于聚合或者非聚合。聚合的时候用CComCreator< CComAggObject< x > >,非聚合时候使用CComCreator< CComObject< x >。
创建组件
CComObject<CMath>* ptrMath;
CComObject<CMath>::CreateInstance( &ptrMath );
CComPtr<IMath> pMath = ptrMath;
转载于:https://www.cnblogs.com/fanzi2009/archive/2010/04/19/1715418.html