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可变参数接口设计在模板编程中应用的一点点总结
概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...
随机推荐
- Mysql(Innodb)如何避免幻读
Mysql(Innodb)如何避免幻读 有意思 MySQL InnoDB支持三种行锁定方式: 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. 间隙锁(Gap Lock):锁定 ...
- EasyUI系列学习(一)-入门
1.什么是jQuery EasyUI jQueryEasyUI是一组基于jQuery的UI插件集合 2.jQueryEasyUI的特点 可以通过html标记来定义用户界面:支持扩展,可根据最近的需求扩 ...
- 如何扒取一个网站的HTML和CSS源码
一个好的前端开发,当看到一个很炫的页面的时候会本着学习的心态,想知道网站的源码.以下内容只是为了大家更好的学习,拒绝抄袭,支持正版. 1 首先我们要有一个chrome浏览器 2 在本地创建相关文件夹 ...
- JS——scroll动画
固定导航栏 1.计算导航栏到顶部的距离值 2.当scrollTop值大于这个距离值就添加定位,当小于距离值后解除定位 注意事项:当导航栏添加定位之后,导航栏就脱离了文档流,也就是不占位了,下面的盒子就 ...
- php入门学习相关函数
1.join(): 定义和用法 join() 函数返回由数组元素组合成的字符串. join() 函数是 implode() 函数的别名. 注释:join() 函数接受两种参数顺序.但是由于历史原因 ...
- spring 415
不支持的媒体类型 spring mvc 使用@requestBody注解json请求时,jQuery有限制,否则会出现 415 错误 1.使用ajax $.ajax({ ...
- Replacing Threads with Dispatch Queues
Replacing Threads with Dispatch Queues To understand how you might replace threads with dispatch que ...
- Mock随机生成数据模拟后台接口
<html> <head> <title>测试</title> <script src="http://code.jquery.com/ ...
- loader__demo_css
环境 node + yarn + webpack4.0 + webpack-cli + style-loader css-loader 文件结构 │ package.json │ webpack.co ...
- sysbench_memory
对于内存而言,这里--memory-total-size=100G 就是 意味着 total number of events: 104857600 1. --memory-total-size=10 ...