在没真正接触c++  模板编程之前。真的没有想到c++ 还能够这么用。最大的感触是:太灵活了,太强大了。

最初接触模板威力还是在Delta3d中,感觉里面的模板使用实在是灵活与方便,特别是dtAI中使用了大量的模板,大大增强了库的可扩展性。

本文基于《c++ 设计新思维》 而写。

先看一段代码:

#include <iostream>
#include <vector>
#include <list>
using namespace std;
//--------------------------------------------------------------------------------
/////////Widget类型
class SliderWidget
{
public:
SliderWidget()
{
std::cout<<"Slider Widget created"<<std::endl;
}
}; class BoxWidget
{
public:
BoxWidget()
{
std::cout<<"Box Widget created"<<std::endl;
}
};
//--------------------------------------------------------------------------------
//创建widget方法 template <class T>
class OpNewCreateor
{
public:
static T* create()
{
return new T;
}
protected:
~OpNewCreateor(){}
}; template <class T>
class MallocCreator
{
public:
static T* create()
{
void * buf = std::malloc(sizeof(T));
if(!buf) return 0; return new(buf) T;
}
protected:
~MallocCreator(){}
}; template <class T>
class PrototypeCreator
{
public:
PrototypeCreator(T* pObj = 0)
:pPrototype(pObj)
{ }
T* create()
{
return pPrototype ? pPrototype->clone() : 0;
}
T* getPrototype(){return pPrototype;}
void setPrototype(T*pObj){pPrototype = pObj;} protected:
~PrototypeCreator(){}
private:
T* pPrototype;
};
//--------------------------------------------------------------------------------
//存储widget容器类型
template<class T>
class ContainerVec
{
public:
void push(T* widget)
{
mVecContainer.push_back(widget);
}
//protected://Container 不能是保护类型。由于WidgetManager 不继承此类
~ContainerVec(){} private:
std::vector<T*> mVecContainer;//Vector容器
}; template <class T>
class ContainerList
{
public:
void push(T* widget)
{
mListContainer.insert(widget);
} ~ContainerList(){}//Container 不能是保护类型。由于WidgetManager 不继承此类
private:
std::list<T*> mListContainer;//List容器
};
//--------------------------------------------------------------------------------
//--------widget管理类
template <
class T,
template<class > class CreationPolicy = MallocCreator,
template<class > class Container = ContainerVec
>
class WidgetManager :public CreationPolicy<T>
{
public:
typedef CreationPolicy<T> BaseClass;
T* create()
{
T* tmp = BaseClass::create();
mContainer.push(tmp);
return tmp;
} private:
Container<T> mContainer;
}; //--------------------------------------------------------------------------------
typedef WidgetManager<BoxWidget,OpNewCreateor,ContainerVec> BoxWidgetManager;
typedef WidgetManager<SliderWidget,OpNewCreateor,ContainerList> SliderWidgetManager;
//-------------------------------------------------------------------------------- int main()
{
BoxWidgetManager boxWidgetManager; BoxWidget * boxWidget = boxWidgetManager.create(); cout << typeid(BoxWidgetManager).name() << endl; system( "pause");
}

什么是基于Policy编程

1. Policies机制是由templates和多继承组成 。

2. 而所谓policy,乃用来定义一个class或class template的接口,该接口由 “内隐型别定义 inner type definition),成员函数、或成员变量之中的一个或所有组成。

3. policy接口和一般传统的class接口(virtual函数)不同。它比較 松散,这是由于policies 是语法导向(syntax oriented)而非标记导向(signature oriented)。

也就是说上面的  createpolicy 明白定义的是:如何的语法构造符合其所规范的class”,而非“必须实作出哪些函数”。createpolicy 并没有规范create()是virtual 还是static,它仅仅要求必须定义出create函数。

4. 假设一个模板使用了policies,我们称其为host class 。如上面的widgetmanager。

Policy class 的析构函数

1. 大部分情况下。host class 会以 public 继承  方式从某些policies 派生而来,因此 使用者能够将一个host class 转换为一个 policy class ,并于稍后delete 该指针。

除非policy class 定义了一个 虚析构函数(virtual destructor) ,否则 delete一个指向policy class 指针。会有问题(最起码 这样会使得 host class 的析构函数没调用)

2. 假设把policy class 的析构函数 定义成虚析构函数。会妨碍policy的静态连接特性。也会影响运行效率。

(引入一份vptr,也会带来额外开销),所以尽量避免虚析构函数

3. 很多policy class 并无数据成员,纯粹仅仅是一个规范行为,policy class应该採用一个轻便而有效率的解法------定义一个non-vritual protected 析构函数。这样保证了仅仅有继承者才干摧毁这个policy对象。

通过不全然具化而获得选择性机能

1. 意思是: 假设class template 有一个成员函数并未曾被用到。它就不会被编译器所详细实现出来。

以policy class 定制结构

通过policy class 不但能够定制行为,如要能够create。并且还能够定制结构。

这个重要的性质使得policy-based design 超越了简单的型别泛化(type genericity),后者对于容器(container class )效力卓越。 (如上面的container policy)

下一步: c++ template  traits

c++ 基于Policy 的 模板编程的更多相关文章

  1. 一个简单的INI读写文件类,基于C++的模板编程实现,使用超级方便

    GITHUB链接:https://github.com/brofield/simpleini 主体代码: /** @mainpage <table> <tr><th> ...

  2. Halcon编程-基于形状特征的模板匹配

    halcon软件最高效的一个方面在于模板匹配,号称可以快速进行柔性模板匹配,能够非常方便的用于缺陷检测.目标定位.下面以一个简单的例子说明基于形状特征的模板匹配.      为了在右图中,定位图中的三 ...

  3. JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有)

    前言:最近园子里多了许多谈语言.谈环境.谈逼格(格局)的文章,看看笑笑过后,殊不知其实都是然并卵.提升自己的技术才是王道.之前博主分享过多篇bootstrap组件的文章,引起了很多园友的关注和支持,看 ...

  4. c++模板编程-typename与class关键字的区别

    最近一直在研究c++模板编程,虽然有些困难,但希望能够坚持下去.今天,在书上看见一个讨论模板编程typename与class两个关键字的区别,觉得挺有意义的,就把它们给总结一下. 先看一个例子: te ...

  5. 出位的template.js 基于jquery的模板渲染插件

    找了好几款基于jquery的模板渲染插件,无一感觉很难用(教程较少.绑定不统一),也可能我智商问题,比如jquery template.js .jtemplate.js. 然后在github上找到这一 ...

  6. JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

    前言:之前发表过一篇  JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理 ...

  7. 基于SSE4和多核编程的电子相册的实现

    基于SSE4和多核编程的电子相册的实现   摘要:电子相册中前后两张图片的切换会产生淡入淡出效果,而且切换过程中需要大量的中间计算过程,而SSE4和多核编程技术能够有效加快中间的计算过程,有效减少图片 ...

  8. 基于HALCON的模板匹配方法总结

    注:很抱歉,忘记从转载链接了,作者莫怪.... 基于HALCON的模板匹配方法总结 很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多 ...

  9. C++ 11可变参数接口设计在模板编程中应用的一点点总结

    概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...

随机推荐

  1. MVC系列学习(十)-生成URL与表单

    本次学习,在路由配置信息中,有两个路由规则,在网站第一次启动的时候,注册了两个路由表 1.动态生成url A.在路由规则中,因为Default在前面,所以最新找到该路由表,此时不管 自己定义的控制器名 ...

  2. 跨平台键鼠共享软件synergy使用

    如果共享的机子都是win系统的话,也可以使用 无界鼠标. 这里主要讲跨平台通用的synergy.下载地址:http://synergy-project.org/ 注意1:最好下载同一位数,同一版本的. ...

  3. 巧用Eclipse Java编辑器调试

    在使用Eclipse开发Java Web应用时,使用的编辑器不但能够为开发者提供代码编写.辅助提示和实时编译等常用功能,而且还能够对Java源代码进行快捷修改.重构和语法纠错等高级操作.通过Eclip ...

  4. JS高级——eval

    eval函数可以用来将字符串转换成JavaScript代码并且运行 <script> eval('var a=10'); console.log(a);//10 </script&g ...

  5. JS——旋转木马

    1.opacity和zIndex的综合运用 2.样式的数组的替换:向右边滑动---删除样式数组第一位并在数组最后添加:向左边滑动---删除样式数组最后一位并在数组前添加 3.开闭原则,只有当回调函数执 ...

  6. linux共享库的版本控制

    前几天看到一篇介绍linux共享库版本控制及使用的文章,觉得不错,这里就与大家分享一下. 1. Linux约定 经常看到Linux中,共享库的名字后面跟了一串数字,比如:libperl.so.5.18 ...

  7. PHP 之递归遍历目录与删除

    /** * @Description: 递归查询目录文件 * @Author: Yang * @param $path * @param int $level * @return array */ f ...

  8. 查询数据表行数 然后循环查找表 添加数据到ITEMS

    ;i<tbBiao.Rows.Count;i++) { string TableName = (tbBiao.Rows[i]["Table"]).ToString(); tb ...

  9. C# 后台POST提交方式

    1.第一种方式:用最新框架,但是针对IIS服务器的操作系统有关系,非R2的收不到数据: using (var reqConts = new MultipartFormDataContent()) { ...

  10. SWING界面

    import java.awt.FlowLayout;import javax.swing.*;import java.awt.Container; public class kk extends J ...