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: