c++ 基于Policy 的 模板编程
在没真正接触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 的 模板编程的更多相关文章
- 一个简单的INI读写文件类,基于C++的模板编程实现,使用超级方便
GITHUB链接:https://github.com/brofield/simpleini 主体代码: /** @mainpage <table> <tr><th> ...
- Halcon编程-基于形状特征的模板匹配
halcon软件最高效的一个方面在于模板匹配,号称可以快速进行柔性模板匹配,能够非常方便的用于缺陷检测.目标定位.下面以一个简单的例子说明基于形状特征的模板匹配. 为了在右图中,定位图中的三 ...
- JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有)
前言:最近园子里多了许多谈语言.谈环境.谈逼格(格局)的文章,看看笑笑过后,殊不知其实都是然并卵.提升自己的技术才是王道.之前博主分享过多篇bootstrap组件的文章,引起了很多园友的关注和支持,看 ...
- c++模板编程-typename与class关键字的区别
最近一直在研究c++模板编程,虽然有些困难,但希望能够坚持下去.今天,在书上看见一个讨论模板编程typename与class两个关键字的区别,觉得挺有意义的,就把它们给总结一下. 先看一个例子: te ...
- 出位的template.js 基于jquery的模板渲染插件
找了好几款基于jquery的模板渲染插件,无一感觉很难用(教程较少.绑定不统一),也可能我智商问题,比如jquery template.js .jtemplate.js. 然后在github上找到这一 ...
- JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化
前言:之前发表过一篇 JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理 ...
- 基于SSE4和多核编程的电子相册的实现
基于SSE4和多核编程的电子相册的实现 摘要:电子相册中前后两张图片的切换会产生淡入淡出效果,而且切换过程中需要大量的中间计算过程,而SSE4和多核编程技术能够有效加快中间的计算过程,有效减少图片 ...
- 基于HALCON的模板匹配方法总结
注:很抱歉,忘记从转载链接了,作者莫怪.... 基于HALCON的模板匹配方法总结 很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多 ...
- C++ 11可变参数接口设计在模板编程中应用的一点点总结
概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...
随机推荐
- 2 我们的C#学习方法
在这里我们借鉴了一种行之有效的学习编程语言的方法,并在此基础上进行了相应的改良.我们在培训新人中使用后,发现这种学习方法是非常有效的. 你通过做以下几个步骤来一步步学习C#语言. 1. 搞懂每一个我们 ...
- HTML 表单 存为EXCEL文件时 中文显示乱码
在做宣传品发放系统时,需求要把数据库查询的记录生成表单并转存excel文件. 在转存的EXCEL文件中文显示乱码,表格和其他字符正常,检查后发现是创建EXCEL文件打开模式不对 之前: myfile ...
- React Native常用组件在Android和IOS上的不同
React Native常用组件在Android和IOS上的不同 一.Text组件在两个平台上的不同表现 1.1 height与fontSize 1.1.1只指定font,不指定height 在这种情 ...
- C# GridView使用方法
public void Point_databind(PointList pl) { chart1.Series.Clear(); //清空图表 Series s1 = new Series(); / ...
- IIS中实现http自动转换到https
IIS中实现http自动转换到https修改以下文件:C:\WINDOWS\Help\iisHelp\common\403-4.htm 为以下内容<!DOCTYPE HTML PUBLIC &q ...
- (转) 分布式文件存储FastDFS(七)FastDFS配置文件详解
http://blog.csdn.net/xingjiarong/article/details/50752586 配置FastDFS时,修改配置文件是很重要的一个步骤,理解配置文件中每一项的意义更加 ...
- 企业级mysql数据库完全备份、增量备份脚本
企业完全备份脚本 [root@client ~]# vim /opt/mysql_bak_wanbei.sh #!/bin/bash #MySQL数据库完全备份脚本 #设置登录变量 MY_USER=& ...
- JS数组reduce()方法
1.语法 arr.reduce(callback,[initialValue]) reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上 ...
- 本地读取服务器Xml文件及本地读本地的xml
updateUrl="ServerUrl"(服务器路径) WebClient wc = new WebClient(); Stream stream = wc.OpenRead(u ...
- 使用vscode,新建.vue文件,tab自动生成vue代码模板
第一步: 新建模板并保存 文件 --> 首选项 --> 用户代码片段 --> 输入vue,选择vue.json -->复制 第三步中的模板内容中内容保存 第二步: 添加配置,让 ...