ATL对聚合的支持
ATL通过CComCreator2模板类以及和聚合相关的宏来支持聚合。
CComCreator2的定义:
template <class T1, class T2>
class CComCreator2
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
ATLASSERT(ppv != NULL);
return (pv == NULL) ?
T1::CreateInstance(NULL, riid, ppv) :
T2::CreateInstance(pv, riid, ppv);
}
};
模板参数T1 和T2 可以是CComCreator或CComFailCreator. 模板参数T1 用来创建非聚合情况下的组件;T2创建被聚合情况下的组件。
和聚合相关的宏有三个:
DECLARE_NOT_AGGREGATABLE //不支持聚合
DECLARE_AGGREGATABLE //支持聚合
DECLARE_ONLY_AGGREGATABLE //仅支持聚合
三个宏定义如下:
#define DECLARE_NOT_AGGREGATABLE(x) public:/
typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComFailCreator<CLASS_E_NOAGGREGATION> > _CreatorClass;
#define DECLARE_AGGREGATABLE(x) public:/
typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass;
#define DECLARE_ONLY_AGGREGATABLE(x) public:/
typedef ATL::CComCreator2< ATL::CComFailCreator<E_FAIL>, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass;
通过宏的定义可以清楚的看到组件的创建过程。
如果组件不支持聚合,那么T2就是CComFailCreator<CLASS_E_NOAGGREGATION>。若想创建被聚合情况下的组件,那么就会调用CComFailCreator::CreateInstance(),然后直接返回参数CLASS_E_NOAGGREGATION。
同样,如果组件仅支持聚合,那么T1就是CComFailCreator<E_FAIL>,创建时直接返回E_FAIL。
设计模式中工厂创建模式是比较常用的模式之一。使用工厂方法可以根据需要动态的创建产品家族中的一员。但在有些情况下,待创建的对象在编码时或者说在编译期是很明确的,不会动态的增加。这个时候,使用模板机制在静态情况下实现工厂模式来创建对象将是更好的选择,借助编译期的优化,达到性能的提升。想到这儿再看一遍<<Modern C++ Design>>…