• 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


  • 相关阅读:
    ffmpeg参数说明
    【FFmpeg】FFmpeg常用基本命令
    ffmpeg最全的命令参数
    数据库总结
    linux redis安装及JAVA使用jedis
    记录一次工作中jvm被linux杀死的调查
    ExecutorService线程池submit的使用
    java四种引用与回调函数
    java排序
    NIO教程笔记
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6958885.html
Copyright © 2020-2023  润新知