1: #include <iostream> 
     2: #include <string> 
     3: 
     4: 
     5: using namespace std;
     6: 
     7: 
     8: const int NO_OBJECTS = 8;
     9: 
    10: ///////////////////////////////////////////////////////////////////////////////
    11: //
    12: // Functor template class:
    13: // 
    14: // Keeps a pointer to a called object ( = object_ ) and 
    15: // keeps a pointer to a method of this object that takes a cont int 
    16: // as parameter and returns void ( = callback_ ).
    17: // This method can be called back by either the:  
    18: //     void Call( const int index )
    19: // or the overloaded operator() method: 
    20: //     void operator() ( const int index )
    21: //      
    22: ///////////////////////////////////////////////////////////////////////////////
    23: template <class CCalledObject>
    24: class CFunctor
    25: {
    26: public:
    27:     CFunctor( CCalledObject* object, void (CCalledObject::*callback)(const int) ) 
    28:         : object_(object), callback_(callback)
    29:         {
    30:         }
    31: 
    32:     virtual ~CFunctor() {};
    33:         
    34:     // the overloaded operator() method calls object_'s callback_ method
    35:     void operator() ( const int index )
    36:         {
    37:         (*object_.*callback_)( index );
    38:         }
    39: 
    40:     // the Call() method calls object_'s callback_ method
    41:     void Call( const int index )
    42:         {
    43:         (*object_.*callback_)( index );
    44:         }
    45: 
    46: private:
    47:     CCalledObject *                 object_;
    48:     void (CCalledObject::*callback_)(const int);
    49: };
    50: 
    51: ///////////////////////////////////////////////////////////////////////////////
    52: //
    53: // This class is going to be the concrete object, thats method Print() is
    54: // going to be called back.
    55: //
    56: // Attention: 
    57: //    the Print() method must have the exactly the same signature as the
    58: //    CFunctor template classes callback_ member.
    59: //    If you want to call back methods with different signatures you
    60: //    will have to adapt the CFunctor's callback_ member to your needs.
    61: //
    62: ///////////////////////////////////////////////////////////////////////////////
    63: class CFunctorTest
    64: {
    65: 
    66: public:
    67: 
    68:  void Print( const int index )
    69:     {
    70:     cout << "CFunctorTest::Print(): I am object number " << index << endl;
    71:     }
    72: 
    73: };
    74: 
    75: ///////////////////////////////////////////////////////////////////////////////
    76: //
    77: // Create NO_OBJECTS CFunctorTest objects and feed a pointer to this object 
    78: // and a pointer to the objects Print() method to the CFunctor template class.
    79: // Then call the Print method via the Call() and the overloaded operator()
    80: // method of the CFunctor template class. 
    81: //
    82: ///////////////////////////////////////////////////////////////////////////////
    83: int main( void )
    84: {
    85:     CFunctorTest *  testObject[NO_OBJECTS];
    86:     CFunctor<CFunctorTest> *  arrFunctor[NO_OBJECTS];
    87: 
    88:     for ( int i = 0; i < NO_OBJECTS; ++i )
    89:         {
    90:         // create called objects
    91:         testObject[i] = new CFunctorTest();
    92:         // create a functor for each called object and feed pointer to 
    93:         // of this object and it's Print() method to this functor:
    94:         arrFunctor[i] = new CFunctor<CFunctorTest>( testObject[i], &CFunctorTest::Print );
    95:         // call functor, which again calls method of object
    96:         arrFunctor[i]->Call(i);    // call via Call() method
    97:         (*arrFunctor[i]) (i);      // call via overloaded operator() method
    98:         }
    99: 
   100:     // delete all objects
   101:     for ( int i = 0; i < NO_OBJECTS; ++i )
   102:         {
   103:         delete arrFunctor[i];
   104:         delete testObject[i];   
   105:         }
   106: 
   107:     return EXIT_SUCCESS;
   108: }
   109: 
   110: