【C++泛型编程】基于策略(Policy)的类设计
来源:互联网 发布:极乐宿舍使用软件 编辑:程序博客网 时间:2024/06/07 12:40
基于策略(Policy)的类设计是将templates和多重继承组合起来,这样可以产生程序库中的“设计元素”。Policies由templates和多重继承组成。一个class如果使用了policies,就称其为host class,那是一个拥有多个template参数的class template,每一个参数代表一个policy.host class所有的机能都来自policies,运作起来就像是一个聚合了数个policies的容器。
1.什么是Policy?
它是用来定义一个class或class template的接口,该接口由下面项目的之一或 全部组成:内隐型别定义(如typedef int * pointer)、成员函数和成员变量。Policies有点类似设计模式中的Strategy,只不过policies更注重编译器。而Strategy更注重运行期。
例子1:定义一个ploicy 用来产生对象,Creator policy是一个带有型别为T的class template,它必须提供一个名为Create()的函数给外界使用,此函数不接受参数,返回一个指向T的指针。下面是三种产生对象的方法即policy:
Policy 1:template<class T>struct OpNewCreator{static T * Create(){return new T;}};Policy 2:template<class T>struct MallocCreator{static T * Create(){void* buf=std::malloc(sizeof(T));if(!buf) return 0;elsereturn new(buf) T;}};Policy 3:template<class T>struct PrototypeCreator{PrototypeCreator(T* pObj=0):pPrototype_(pObj){} T * Create(){ return ppPrototype_? pPrototype_->Clone():0;}T *GetPrototype(){ return pPrototype_;}void setPrototype(T* pObj){pPrototype_=pObj;}private:T * pPrototype_;};上面三个policy称为policy classes.这些东西并不是用来单独使用,主要是用于继承或被内含于其他的类。
Creator policy并没有规定Create()必须是static 还是virtual,只要求class必须定义一个Create().你可以定义多个policy class,但是必须遵循统一的接口。
2.利用前面的Creator Policy,怎么样设计一个类?
我们可以用复合或继承的方式使用前面定义的三个类之一。
例如:
template<class CreationPolicy>class WidgetManager:public CreationPolicy{ };如果一个类采用了一个或多个policy class,就称其为host或host classes.上面定义的WidgetManager采用了一个policy,称其为host class.Hosts主要负责把上面定义的policies的结构和行为组成一个风复杂的结构和行为。
用户可以将WidgetManager实例化,传进一个用户指定的Policy,如下:
typedef WidgetManager<OpNewCreator<Widget> > MyWidgetPtr;
当一个MyWidgetPtr需要产生一个Widget对象时,它就调用它的policy子对象OpNewCreator<Widget>所提供的Create()函数。WidgetManager是用来选择生成策略(Creation policy)的(基于Policy设计类的宗旨)。
3.怎么样为host class 中的Policy classes的参数设定缺省值?
在前面可以看到,policy 类的template参数是非常累赘的。使用者每次都需要向Policy 类(如OpNewCreator)传递一个template参数,表示需要创建的对象。如果使用者操作的对象固定,就不需要每次都传递这个参数,可以采用默认的对象来实例化。
a.采用Template Template参数来设定缺省值
template <template<class Created> class CreationPolicy>class WidgetManager:public CreationPolicy<Widget>{.......}//Created 是CreationPolicy的参数。CreationPolicy 是WidgetManager的参数。上面的Widget已经写入程序库,使用时不需要再传一次参数给policy.可以采用如下方式使用:
typedef WidgetManager<OpNewCreator> MyWidgetMgr;
如果用户想要用WidgetManger的相同策略产生一个Gadget对象,如下:
template<template<class> class CreationPolicy>class WidgetManager:public CreationPolicy<Widget>{void DoSomething(){Gadget *pW=CreationPolicy<Gadget>.Create();}};
注:为常用的policy提供缺省的参数:
template <template<class> class CreationPolicy=OPNewCreator>class WidgetManager...;policies有丰富的型别信息及静态连接等特性,在编译期才把host class和policies结合在一起,所以是建立“设计元素”时的本质性东西。
b.利用Template成员函数来定义policy class。
我们可以重新定义之前的policy为非template class,该函数内部定义一个template函数,如下:
struct OpNewCreator{template<class T>static T *Create(){ return new T;}};这样定义的policy,对旧的编译器比较兼容。这样的policy难以讨论,定义和运用。
4.Policy Classes的析构函数
大部分情况下,host class会以public方式继承某些policies,所以调用者可以将一个host class自动转为一个policy class,并delete 该指针。除非为policy class定义虚析构函数,否则delete一个执行policy class的指针,会产生不可预期的结果。然而如果为policy定一个虚析构函数,会影响policy的静态链接特性,也会影响执行效率。
许多policies并没有数据成员,只纯粹提供一个接口。虚函数的加入会为对象的大学带来额外开销,所以虚函数应该尽量避免。
一个解决办法是host class 派生policy class时候,采用protected或private继承。但这样会失去丰富的policies特性。
另一个有效的解法是定义一个protected的析构函数。由于是protected,只有派生而得的类才可以摧毁这个policy对象。这样外界就不可能delete一个指向policy class的指针。由于析构函数不是虚函数,不会带来大小或速度上的额外开销。
5.通过不完全具现化获取选择机能
C++的有趣特性,造就了policies的丰富特性。如果class template有一个成员函数没有用到,它就不会被编译器具体实现出来。编译器不会理会,甚至不进行语法检验。这样就可以让host class有机会并使用policy class的可选特性。如下:
template<template<class> class CreationPolicy>class WidgetManage:public CreationPolicy<Widget>{void SwitchPrototype(Widget *pNewPrototype){CreationPolicy<Widget> &myPolicy=*this;delete myPolicy.GetPrototype();myPolicy.SetPrototype(pNewPrototype);}};
如果你采用一个定义了SetPrototype()函数的Creator policy来实例化WidgetManager,就可以使用SwitchPrototype()函数。若采用不支持SetPrototype()函数的Creator policy来实例化WidgetManager,就会参数编译错误。如果你采用一个不支持SetPrototype()函数的Creator policy来实例化WidgetManager,如果使用在没有调用SwitchPrototype(),程序是合法的。
6.用Policy class定制结构
templates的限制之一是你无法定制class的结构,只能定制其行为。然而基于policy 类的设计支持结构方面的定制。一般像如下定义:
template<class T>class SmartPtrStorage{public:typedef T *PointerType;typedef T& ReferenceType;protected:PointerType GetPointer(){ return pointee_;}void SetPointer(PointerType ptr){pointee_=ptr;}private:PointerType pointee_;};
复制搜索
复制搜索
- 【C++泛型编程】基于策略(Policy)的类设计
- 基于策略(policy)的类设计方法
- 用C++ 模板做代码设计的三类方法及代码——基于策略Policy-based design
- 学习 Policy based design - 读C++设计新思维-泛型编程与设计模式的应用
- 基于Policy的Class设计, 读后感
- c++ 基于Policy 的 模板编程
- Linux平台下基于BitTorrent应用层协议的下载软件开发--策略管理模块(policy.c)
- WebService基于契约编程的基础-WS-Policy学习笔记
- java设计模式之strategy(策略模式)和policy模式(泛化的strategy模式)
- 策略梯度(Policy Gradients)的理解
- 泛型<编程>:基于策略的basic_string实现
- 设计模式初探-策略模式(STRATEGY),别名政策(Policy)
- Linux平台下基于BitTorrent应用层协议的下载软件开发--策略管理模块(policy.h)
- 《Java编程思想》泛型中的策略设计模式
- java policy 策略
- oracle 策略POLICY学习
- 基于C 的speex编程
- 活动目录(AD)下的组策略(group policy)
- 32位和64位系统区别及int字节数
- 如何让IOS应用从容地崩溃
- Python学习笔记之集合类型(set, frozeset)
- Tomcat 下Web项目的定时任务
- asihttprequest
- 【C++泛型编程】基于策略(Policy)的类设计
- xCode 4.X 免证书真机公布及调试
- Activity生命周期理解之一 启动一个Activity
- 常见Js复制代码
- Spring 声明式事务,propagation属性列表
- request.getParameter()和request.getAttribute()
- flex 鼠标变成手型
- nandflash驱动分析 针对K9GAG08U0D uboot1.1.6(上)
- thinkPHP不为人知的函数