简体   繁体   中英

How do I obtain a function pointer for a generic class member function?

I need to instantiate different objects in an array and call their execute methods depending on the data I receive from a socket. I'd like to avoid using switch and if statements in this case.

The code works perfectly, as long as I'm not working with templates. Once I work with templates, it fails to compile.

Problem is: I can't figure out a workaround for this typedef, since it's not allowed to use it with templates. I've seen some posts here and etc, but couldn't find anything helpful till now.

I'm pasting a basic test code for the class I'm having trouble with and the main. The rest of the code won't interfere.

class Command {
public:
   template<class T>
   typedef void (T::*Action)();  
   Command( T* object, Action method ) {
      m_object = object;
      m_method = method;
   }
   void execute() {
      (m_object->*m_method)();
   }
private:
   T* m_object;
   Action m_method;
};


int main( void ) {
   Queue<Command> que;
   Command* input[] = { new Command( new test, &test::m1),
                        new Command( new test, &test::m2),
                        new Command( new test, &test::m3)};

   for (int i=0; i < 3; i++)
      que.enque( input[i] );

   for (int i=0; i < 3; i++)
      que.deque()->execute();
   cout << '\n';
}

Found a solutiuon. I'm posting it here for those with the same problem.

QList is a template class in QT. For those who are not uing QT, QList should be replaced by something like this: "typedef std::list list; list list_of_objects."

Here it is:

class abstract
{
public:
   virtual void execute(int z) = 0;
};

class Test: public abstract
{
public:
    void execute(int z)    { qDebug() << "-test  " << z; }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QList<abstract*> list_of_objects;

/ Now able to associate different class objects to different indexes. For example: Test in index 0, Test2 in index 1... and so on /

    list_of_objects.insert(0,new Test); 
    list_of_objects.at(0)->execute(1000);

    return a.exec();
}

Thanks for the help.

You can't use T inside Command since it is not the name of a type (except in the typedef ).

Command needs to be a class template.

template<class T>
class Command {
public:
   typedef void (T::*Action)();  
   Command( T* object, Action method ) {
      m_object = object;
      m_method = method;
   }
   void execute() {
      (m_object->*m_method)();
   }
private:
   T* m_object;
   Action m_method;
};

int main( void ) {
   Queue<Command<test>> que;
   Command<test>* input[] = { new Command<test>( new test, &test::m1),
                              new Command<test>( new test, &test::m2),
                              new Command<test>( new test, &test::m3)};

   for (int i=0; i < 3; i++)
      que.enque( input[i] );

   for (int i=0; i < 3; i++)
      que.deque()->execute();
   cout << '\n';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM