c++ 泛型 编程 之 Functor 设计模式
来源:互联网 发布:大象学社软件下载 编辑:程序博客网 时间:2024/05/16 09:44
完整代码见:
http://download.csdn.net/detail/zhuyingqingfen/8457091
#ifndef FUNCTOR_H_#define FUNCTOR_H_#include "typelists.h"#include "typetraits.h"template<typename R,class TList>class FunctorImpl;template<typename R>class FunctorImpl<R,NullType>{public:virtual R operator()() = 0;//Clone 目的是为了产生FunctorImpl对象的一份多态(通过基类指针调用实际的对象的Clone方法)拷贝//这个也用到了“协变式返回类型"特性,即你可以在子类中改写返回值类型,指向子类(pointer to derived class)virtual FunctorImpl * Clone()const = 0;virtual ~FunctorImpl(){}//虚构造函数的作用是当删除FunctorImpl的指针时,能够调用FunctorImpl的//派生类的指针。};template<typename R,typename P1>class FunctorImpl<R,TYPELIST_1(P1)>{public:virtual R operator()(P1) = 0;virtual FunctorImpl * Clone()const = 0;virtual ~FunctorImpl(){}};template<typename R,typename P1,typename P2>class FunctorImpl<R,TYPELIST_2(P1,P2)>{public:virtual R operator()(P1,P2) = 0;virtual FunctorImpl * Clone()const = 0;virtual ~FunctorImpl(){}};template<class ParentFunctor,typename Fun>class FunctorHandler://普通函数实现public FunctorImpl<typename ParentFunctor::ResultType,typename ParentFunctor::ParmList>{public:typedef typename ParentFunctor::ResultType ResultType;FunctorHandler(const Fun & fun):_fun(fun){}FunctorHandler*Clone()const{return new FunctorHandler(*this);}ResultType operator()(){return _fun;}ResultType operator()(typename ParentFunctor::Parm1 p1){return _fun(p1);}ResultType operator()(typename ParentFunctor::Parm1 p1,typename ParentFunctor::Parm2 p2){return _fun(p1,p2);}private:Fun _fun;};template<class ParentFunctor,typename PointerToObj,typename PointerToMemFn>class MemFunHandler : public FunctorImpl<typename ParentFunctor::ResultType,typename ParentFunctor::ParmList>{public:typedef typename ParentFunctor::ResultType ResultType;MemFunHandler(const PointerToObj & pOjb,PointerToMemFn pMemFn):_pObj(pOjb),_pMemFn(pMemFn){}MemFunHandler * Clone()const {return new MemFunHandler(*this);}ResultType operator()(){return ((*_pObj).*_pMemFn)();}ResultType operator()(typename ParentFunctor::Parm1 p1){return ((*_pObj).*_pMemFn)(p1);}ResultType operator()(typename ParentFunctor::Parm1,typename ParentFunctor::Parm2){return ((*_pObj).*_pMemFn)(p1,p2);}private:PointerToObj _pObj;PointerToMemFn _pMemFn;};template<typename R,class TList>class Functor{public:typedef R ResultType;typedef TList ParmList;typedef typename TypeAtNonStrict<TList,0,EmptyType>::Result Parm1;typedef typename TypeAtNonStrict<TList,1,EmptyType>::Result Parm2;//用来处理仿函数和普通函数template<typename Fun>explicit Functor(const Fun & fun):spImpl(new FunctorHandler<Functor,Fun>(fun)){}//用来处理普通类成员函数template <class P, typename MF>explicit Functor(P const& pobj, MF memfun):spImpl(new MemFunHandler<Functor,P,MF>(pobj,memfun)){}Functor():spImpl(0){}Functor(const Functor & src){spImpl = src.spImpl?src.spImpl->Clone():NULL;}Functor& operator = (const Functor &){if (this != &src) {if (spImpl) delete spImpl;spImpl = src.spImpl? src.spImpl->Clone():NULL;}return *this;}R operator()(){return (*spImpl)();}R operator()(Parm1 p1){return (*spImpl)(p1);}R operator()(Parm1 p1,Parm2 p2){return (*spImpl)(p1,p2);}private:typedef FunctorImpl<R,TList> Impl;std::auto_ptr<Impl>spImpl;};#endif
测试:
struct TestFunctor{void operator()(int i,double d){std::cout<<"test functor:"<<i<<" "<<d<<std::endl;}};void MysimpleFunction(int i,double d){std::cout<<"test functor:"<<i<<" "<<d<<std::endl;}class MyClass{public:void test(int i){std::cout<<i<<std::endl;}void print(){std::cout<<"Myclass:print()"<<std::endl;}}; void functor_test(){std::cout<<"Functor Test:-----------"<<std::endl;TestFunctor f;Functor<void, TYPELIST_2(int,double)>cmd(f);typedef void (*PFun)(int,double);PFun pf = MysimpleFunction; /*(摘自网络)按照&运算符本来的意义,它要求其操作数是一个对象,但函数名不是对象(函数是一个对象),本来&test是非法的,但很久以前有些编译器已经允许这样做, c/c++标准的制定者出于对象的概念已经有所发展的缘故,也承认了&test的合法性。 因此,对于test和&test你应该这样理解,test是函数的首地址,它的类型是void (),&test表示一个指向函数test这个对象的地址, 它的类型是void (*)(),因此test和&test所代表的地址值是一样的,但类型不一样。test是一个函数,&test表达式的值是一个指针! 跟此问题类似的还有对一个数组名取地址。 int a[100]; printf("%p\n", a); printf("%p\n", &a[0]); 打印值一样。 但是数组名a,指向的是具有100个int类型的组数; &a[0]指向的是元素a[0]。 即他们的值相同,但指向的类型不同*/ std::cout<<" 函数"<<MysimpleFunction<<" "<<&MysimpleFunction<<std::endl;Functor<void, TYPELIST_2(int,double)>cmd2(pf);//Functor<void, TYPELIST_2(int,double)>cmd2(&MysimpleFunction);Functor<void, TYPELIST_2(int,double)>cmd3(static_cast<PFun>(MysimpleFunction));cmd(2,3.4);cmd2(11,3.4455);cmd3(3,4.55);MyClass c;Functor<void,TYPELIST_0()> ff(&c,&MyClass::print);ff();std::cout<<"End Functor Test.........."<<std::endl;}
1 0
- c++ 泛型 编程 之 Functor 设计模式
- Object-c 编程之道 IOS设计模式解析
- C嵌入式编程设计模式
- 软件架构设计之Utility模块——Functor
- Command模式,Functor与对之应用的一些想法
- 【读书笔记】Objective-C编程之道:iOS设计设计模式解析(1)-原型模式
- 设计模式之接口编程
- 编程基础之设计模式
- Objective-C编程之道:iOS设计模式解析(一)工厂模式
- Objective-C编程之道:iOS设计模式解析(一)工厂模式
- C编程之通讯录设计
- C编程之停车场设计
- 【编程素质】多线程编程之设计模式
- iOS书摘之Objective-C编程之道 iOS设计模式解析
- (C#)设计模式 之 单例模式
- 设计模式之命令模式(c++)
- 设计模式之状态模式(c++)
- 设计模式之工厂模式(c++)
- NSDateFormatter的格式串详解(转)
- core dump为何不能生成core文件
- html+css实现百叶效果
- Thinking in Java学习笔记 DelayQueue和Delayed接口
- 异常与错误的处理
- c++ 泛型 编程 之 Functor 设计模式
- 探秘Java中的String、StringBuilder以及StringBuffer
- SQL_编写一个简单的删除员工信息的存储过程
- "Unity 3D中的内存管理"之读书笔记
- java命令行小例子
- Sonatype Nexus 库被删除的恢复方法
- android http
- 前后台页面参数互传
- 巧用Logcat把日志记录到文件