Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493471
  • 博文数量: 72
  • 博客积分: 1851
  • 博客等级: 上尉
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-16 17:50
文章分类

全部博文(72)

文章存档

2013年(1)

2012年(17)

2011年(51)

2010年(3)

分类: C/C++

2012-07-01 17:11:30

C++标准中,所有关于函数模板的API均在头文件funcitonal,mem_fun,函数模板主要的好处是将类的执行与具体类的实现分离开,这也是command设计模式中的一个关键特征.

    在实现函数模式时,主要就是将类的实参及对象的指针进行保存起来,生成一个对象,到执行该函数时,不用显示原来的类执行函数,而是直接执行函数模板生成的对象即可.这样就实现了分离,那么函数模板的关键之处就是如何保存函数参数,及对象地址,返回数据.那么在涉及模板参数时,就至少有三种类型的参数:对象类型,参数类型及返回类型.

    另外为了执行函数,就必须包含有函数指针,函数对应的行参及对象指针.而三种类型的参数就可以做为模板参数,后面的具体地址及内容就可以做为函数模板的具体构造函数来实现,为了保存具体的地址及行参,就需要定义模板类的私有成员来进行实现.所以,模板的具体定义(这里假设是单参数的函数模板)如下:

  1. template <typename ResultType,typename ParamType,class PointerToObj>
  2. class Functor_t {
  3. private:
  4.     ParamType param1_;
  5.     PointerToObj* pObj_;
  6.     MemFn_t pMemFn_;
  7.     typedef ResultType (PointerToObj::*MemFn_t)(ParamType);
  8. public:
  9.     Functor_t(PointerToObj *pObj,MemFn_t pMemFn,ParamType param1):param1_(param1),pMemFn_(pMemFn),pObj_(pObj)
  10.     {
  11.     }

另外还需要进行执行该函数的形式:obj(),直接通过重载运算符函数就可以实现:

  1. ResultType operator()()
  2.     {
  3.         return (pObj_->*pMemFn_)(param1_);
  4.     }

这样就可以进行调用该函数了:


  1. A a;
  2.     Functor_t<void,int,A> fn(&a,&A::print,2);
  3.     fn();

但是还有一点不足的是每次都需要指明函数模板的一些参数问题,有些不方便,不过这也是函数模板类的特点,可以对其进行封装采用非类模板:函数的形式来完成,这样就可以不用生成对象就可以进行调用:

  1. template<class R,class T,class P> Functor_t<R,P,T> Functor(R (T::*f)(P),T* pT,P param)
  2. {
  3.     return Functor_t<R,P,T>(pT,f,param);
  4. }

这样在调用时,就不用具体指明参数的类型了:

  1. Functor(&A::print,&a,2)();

采用了类似方法,可以构造无参数的函数模板,实现如下:

  1. template <class R,class T>
  2. class Fun_t
  3. {
  4. private:
  5.     R (T::*pmf)();
  6.     T *pT_;
  7. public:
  8.     Fun_t(R (T::*f)(),T *pT):pmf(f),pT_(pT) {
  9.          
  10.     }
  11.     
  12.     R operator()()
  13.     {
  14.         return ((pT_->*pmf))();
  15.     }
  16. };
  17.    
  18. template<class R,class T>
  19. Fun_t<R,T> Fun(R (T::*f)(),T *pT)
  20. {
  21.     return Fun_t<R,T>(f,pT);
  22. }

采用类似方法可以进行扩展至多个参数,其中上面的测试结果如下:

  1. print(i:2).
  2. print(i:2).
  3. no arguments
  4. print(i:1).

具体测试程序及实现见附件. MemFn.zip   

参考资料:

[1] The C++ Programming Language,Bjarne Stroustrup

[2] Modern C++ Design,Andrei Alexandrescu

[3]

[4]

阅读(1627) | 评论(1) | 转发(0) |
0

上一篇:select 机制分析(二)

下一篇:语言中的闭包

给主人留下些什么吧!~~

dan25700151072012-12-30 17:47:31

今天浏览了您的博客,发现里面的文章都写的非常好,楼主您真是个非常有才的人,有些问题想具体请教请教,我的QQ:2376659693 !