Policy Class (Template)
下面的这些Creater叫做“policy class (template)”。它们类似于设计模式里的strategy。它们是语法导向(syntax oriented),而不是标记导向(signature oriented)。换句话说,这些Creater定义的是”怎样的语法构造符合其所规范的class”,而不是“必须实例化那些函数”。
template <class T> struct OpNewCreator { static T* Create() { return new T; } }; template <class T> struct MallocCreator { static T* Create() { void* buf = std::malloc(sizeof(T)); if (!buf) return 0; return new(buf) T; } }; template <class T> struct PrototypeCreator { PrototypeCreator(T* pObj = 0): pPrototype_(pObj){} T* Create() { return pPrototype_ ? pPrototype_->Clone() : 0; } T* GetPrototype() { return pPrototype_; } void SetPrototype(T* pObj) { pPrototype_ = pObj; } private: T* pPrototype_; };
Host Classs Template
使用policy class (template)的叫做“host class (tempalte)”。host class (template)使用组合或者继承的方式使用policy class (template)。host负责把policy提供的结构和行为组合成更复杂的结构和行为。
template <class CreationPolicy> class WidgetManager : public CreationPolicy {}
typedef WidgetManager<OpNewCreator<Widget> > MyWidgetMgr;
emplate template 参数
从上面的使用方法上看,policy(OpNewCreator)还要接收一个模板类参数(Widget),然而作为一个WidgetManager它只能操作Widget,也就是说万一又一次有个程序员传了另外一个类给policy,那么就会因为和WidgetManager不兼容而出现问题。为了避免这种风险,可以使用“template template 参数”
template <template <class Created> class CreationPolicy> class WidgetManager : public CreationPolicy<Widget> {...}
关于template tempalte parameter, 可以这么理解:WidgetManager这个类,是一个带有模板参数的类,它的模板参数是template <class Created> class CreationPolicy>,这个模板参数本身又是一个模板。使用作为模板参数的这个模板给WidgetManager指定基类:CreationPolicy<Widget>。可以印证WidgetManager的模板参数声明和使用的都是一个模板。这个作为WidgetManager的模板参数的模板的参数声明为class Created,使用为CreationPolicy中的Widget。
用模板作为模板参数还有一个好处,那就是:因为现在WidgetManager的模板参数是一个模板,你可以用这个模板来实例化别的模板类。比如在WidgetManager中已经使用了CreationPolicy<Widegt>(作为基类),你也可以把CreationPolicy派其它用途,比如我可以在WidgetManager里面使用CreationPolicy<Gadget>生成一个Gadget。
template <template <class Created> class CreationPolicy = OpNewCreator> class WidgetManager : public CreationPolicy<Widget>{...}