www.Function-Pointer.org
The site dedicated to C and C++ Function Pointers


Exit  Download  Links  Contact  Disclaimer  Main 

The Function Pointer Tutorials

 Extensive Index
 1.  Introduction to Function Pointers
 2.  The Syntax of C and C++ Function Pointers
 3.  How to Implement Callbacks in C and C++ ?
 4.  Functors to encapsulate C and C++ Function Pointers
 5.  Topic Specific Links

4.  Functors to encapsulate C and C++ Function Pointers Main Index Top
   4.1  What are Functors ?
   4.2  How to Implement Functors ?
   4.3  Example of How to Use Functors

4.1  What are Functors ?

Functors are functions with a state. In C++ you can realize them as a class with one or more private members to store the state and with an overloaded operator () to execute the function. Functors can encapsulate C and C++ function pointers employing the concepts templates and polymorphism. You can build up a list of pointers to member functions of arbitrary classes and call them all through the same interface without bothering about their class or the need of a pointer to an instance. All the functions just have got to have the same return-type and calling parameters. Sometimes functors are also known as closures. You can also use functors to implement callbacks.


4.2  How to Implement Functors ? Main Index Top

First you need a base class TFunctor which provides a virtual function named Call or a virtually overloaded operator () with which you will be able to call the member function. It's up to you if you prefer the overloaded operator or a function like Call. From the base class you derive a template class TSpecificFunctor which is initialized with a pointer to an object and a pointer to a member function in its constructor. The derived class overrides the function Call and/or the operator () of the base class: In the overrided versions you call the member function using the stored pointers to the object and to the member function. If you are not sure of how to use function pointers take a look at my Introduction to Function Pointers.


   //-----------------------------------------------------------------------------------------
   // 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){};  // call using operator
      virtual void Call(const char* string) {};       // 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
   };

4.3  Example of How to Use Functors Main Index Top

In the following example we have two dummy classes which provide a function called Display which returns nothing (void) and needs a string (const char*) to be passed. We create an array with two pointers to TFunctor and initialize the array entries with two pointers to TSpecificFunctor which encapsulate the pointer to an object and the pointer to a member of TClassA respectively TClassB. Then we use the functor-array to call the respective member functions. No pointer to an object is needed to make the function calls and you do not have to bother about the classes anymore!


   //-----------------------------------------------------------------------------------------
   // 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. create array with pointers to TFunctor, the base class and ...
      TFunctor** vTable = new TFunctor*[2];

      // ... assign functor addresses to the function pointer array
      vTable[0] = &specFuncA;
      vTable[1] = &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 "()"


      // 5. release
      delete[] vTable;


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

      return 0;
   }

5.  Topic Specific Links Main Index Top


Download zipped Postscript Download PDF Download zipped HTML-Files You can download a zipped Postscript, a PDF or zipped HTML-Files of the tutorials about Function Pointers, Callbacks and Functors!
Download Example Source You can also download the zipped source-files with all examples of the tutorials!


new Newsgroup about function pointers! new


last updated: 10.07.01
© 2000/2001 by lars haendel
All code pieces were highlighted using the free lore's source converter. All trademarks are the sole property of their respective owners. I do NOT promote, speak in the behalf of, advertise or work for ANY computing, news or internet profit business. Everything I do, I do it for fun! If you have questions, annotations, contributions, want to suggest a link or found a bug: Mail me!!!! 

BTW something about bugs: Yes, there are bugs on these pages and they will stay and enjoy their being as long as I find them or you tell me about them. Almost nobody writes a bug report if he encounters an error. But it's so easy for you: Just drop me a few lines in a mail. It won't take you more than 3 minutes. I spend much time to make these pages and I did it for YOU!