functors in C++

punith's Avatar, Join Date: Sep 2007
Go4Expert Member
hi i was going through Functor tutorial on net which had the following example
Code:
class TFunctor
   {
   public:
      virtual void operator()(const char* string)=0;
      virtual void Call(const char* string)=0;
 };

   template <class TClass> class TSpecificFunctor : public TFunctor
   {
   private:
      void (TClass::*fpt)(const char*);
      TClass* pt2Object;

   public:
      TSpecificFunctor(TClass* _pt2Object, void(TClass::*_fpt)(const char*))
         { pt2Object = _pt2Object;  fpt=_fpt; };

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

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

Code:
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;

  TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);
  TSpecificFunctor<TClassB> specFuncB(&objB, &TClassB::Display);
  TFunctor* vTable[] = { &specFuncA, &specFuncB };
  vTable[0]->Call("TClassA::Display called!");        // via function "Call"
  (*vTable[1])   ("TClassB::Display called!");        // via operator "()"
   cout << endl << "Hit Enter to terminate!" << endl;
   cin.get();
   return 0;
   }

Now i tried to replace main() with a class
Code:
class test
{
public:
TClassA objA;
This is not possible now
Code:
TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);
};
How to achieve this when main() is removed.
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
You always have to have a main function in C++; it's the starting point for your program.
punith's Avatar, Join Date: Sep 2007
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
You always have to have a main function in C++; it's the starting point for your program.
But i need this to be a library and the main is present somewhere else
I tried to compile this piece of code with -c option

Last edited by punith; 10Aug2009 at 08:46..
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
OK. What does "This is not possible" mean? Do you get an error?
If so, what is that error?
If not, please explain why you think it is not possible.
punith's Avatar, Join Date: Sep 2007
Go4Expert Member
Sorry for the confusion. I will add it properly this time .

This is my hdr file (hdr.h) file.
Code:
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
   };
This is my CPP file
[code]

Code:
#include "hdr.h"
#include <iostream>
using namespace std;

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 */
   };

class test
     27    {
     28       public:
     29 
     30       // 1. instantiate objects of TClassA and TClassB
     31       TClassA objA;
     32       TClassB objB;
     33 
     34 
     35       TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);
};


I get this error while compiling
Code:
[root@localhost example]# g++ -c hdr.cpp 
hdr.cpp:35: error: expected identifier before ‘&’ token
hdr.cpp:35: error: expected identifier before ‘&’ token
hdr.cpp:35: error: expected ‘,’ or ‘...’
[root@localhost example]#
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
OK, so it looks like you've taken the code from main() and are trying to use it as a class definition.
This won't work; you need to write function code in functions, not in class definitions.
One way if the code must go in a class definition is to have a member function that contains the code from main; that should work OK.
Code:
class test {
public:
  void func() {
    TClassA objA;
    TClassB objB;
    TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);
  }
punith's Avatar, Join Date: Sep 2007
Go4Expert Member
hi now it compiles. I was under the impression that
Code:
TSpecificFunctor<TClassA> specFuncA(&objA, &TClassA::Display);
is actually creating a member function specFuncA(..) under the class test.
punith's Avatar, Join Date: Sep 2007
Go4Expert Member
thanks for replying xpi0t0s now it works for me