在没真正接触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

最新文章

  1. 如何创建 Code Snippet
  2. python中import和from...import区别
  3. 线性表的顺序存储结构C语言版
  4. gnuplot配置HOME目录
  5. Spark往Elasticsearch读写数据
  6. POJ 1507
  7. js,css 和 html 分离,见仁见智
  8. ios中strong, weak, assign, copy
  9. Web Service和Servlet的区别(转)
  10. ThinkPhp学习02
  11. Python基础(十)-模块
  12. IT项目角色标准定义
  13. 计科1702冯亚杰C语言程序设计预备作业
  14. ---perl 模块安装方法
  15. python之tkinter使用-多选框实现开关操作
  16. python - 远程主机执行命令练习(socket UDP + subprocess.Popen()) 练习1
  17. 苹果开发——向App Store提交应用
  18. vue向路由组件传递props
  19. css 发光样式
  20. Golang教程:goroutine信道

热门文章

  1. python框架之Flask基础篇(三)-------- 模版的操作
  2. python--8、面向对象的深入知识
  3. checkbox与文字混排无法对齐到一行的解决办法
  4. facenet
  5. Java jre7及以上版本中的switch支持String的实现细节
  6. vue踩坑之路--点击按钮改变div样式
  7. auto类型推导
  8. Luogu P2922 秘密消息
  9. HDU - 5894 Pocky(概率)
  10. 配置yum仓库和rpm包