{译}函数指针漫谈(4)

使用仿函数封装C和C++函数指针

http://blog.csdn.net/luckheadline
1. 什么是仿函数
    仿函数是带有状态的函数。在C++中,可以认为它们是带有一个或多个存储有状态的私有成员和带有个一个重载操作符()以执行函数的类。仿函数可以使用模板和多态的概念封装C和C++函数指针。我们可以为任意类建立一个成员函数指针列表,然后通过相同的接口调用它们而不影响它们的类。所有的函数需要有相同的返回值和调用参数。有时候仿函数也称闭包。我们也可以用仿函数实现callback。

2. 如何实现仿函数
    首先需要一个基类TFunctor,它提供一个虚函数Call或者虚重载符(),使用它可以调用成员函数。至于是喜欢用重载操作符还是调用Call函数取决于你。从基类可以继承一个模板类TSpecificFunctor,它在构造函数中用一个指向对象的指针和一个成员函数指针初始化。这个继承类重载了函数Call和/或基类的操作符():在重载版本中,使用指向对象的存储指针和成员函数指针调用成员函数。
//-----------------------------------------------------------------------------------------
   // 4.2 How to Implement Functors

   // abstract base class
   class TFunctor
   {
   public:

      // two possible functions to call member function. virtual cause derived
      // classes will use a pointer to an object and a pointer to a member function
      // to make the function call
      virtual void operator()(const char* string)=0;  // call using operator
      virtual void Call(const char* string)=0;        // call using function
   };


   // derived template class
   template <class TClass> class TSpecificFunctor : public TFunctor
   {
   private:
      void (TClass::*fpt)(const char*);   // pointer to member function
      TClass* pt2Object;                  // pointer to object

   public:

      // constructor - takes pointer to an object and pointer to a member and stores
      // them in two private variables
      TSpecificFunctor(TClass* _pt2Object, void(TClass::*_fpt)(const char*))
         { pt2Object = _pt2Object;  fpt=_fpt; };

      // override operator "()"
      virtual void operator()(const char* string)
       { (*pt2Object.*fpt)(string);};              // execute member function

      // override function "Call"
      virtual void Call(const char* string)
        { (*pt2Object.*fpt)(string);};             // execute member function
   };

3. 如何使用仿函数的例子
    下面的例子中,有两个类,提供了函数Display。我们建立指向TFunctor指针的数组并且用两个指向TSpecificFunctor指针初始数组的entries。然后使用仿函数组调用各自的成员函数。不需要指向对象的指针调用函数并且不用再关心那些类了。
//-----------------------------------------------------------------------------------------
   // 4.3 Example of How to Use Functors

   // dummy class A
   class TClassA{
   public:

      TClassA(){};
      void Display(const char* text) { cout << text << endl; };

      /* more of TClassA */
   };

   // dummy class B
   class TClassB{
   public:

      TClassB(){};
      void Display(const char* text) { cout << text << endl; };

      /* more of TClassB */
   };


   // main program
   int main(int /*argc*/, char* /*argv[]*/)
   {
      // 1. instantiate objects of TClassA and TClassB
      TClassA objA;
      TClassB objB;


      // 2. instantiate TSpecificFunctor objects ...
      //    a ) functor which encapsulates pointer to object and to member of TClassA
      TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);

      //    b) functor which encapsulates pointer to object and to member of TClassB
      TSpecificFunctor<TClassB> specFuncB(&objB, &TClassB::Display);


      // 3. make array with pointers to TFunctor, the base class, and initialize it
      TFunctor* vTable[] = { &specFuncA, &specFuncB };


      // 4. use array to call member functions without the need of an object
      vTable[0]->Call("TClassA::Display called!");        // via function "Call"
      (*vTable[1])   ("TClassB::Display called!");        // via operator "()"


      // hit enter to terminate
      cout << endl << "Hit Enter to terminate!" << endl;
      cin.get();

      return 0;
   }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值