Как получить указатель на функцию для универсальной функции-члена класса? - PullRequest
0 голосов
/ 23 февраля 2019

Мне нужно создавать экземпляры различных объектов в массиве и вызывать их методы execute в зависимости от данных, которые я получаю из сокета.Я хотел бы избежать использования switch и if в этом случае.

Код работает отлично, пока я не работаю с шаблонами.Когда я работаю с шаблонами, он не компилируется.

Проблема в том, что я не могу найти обходной путь для этого typedef, поскольку его нельзя использовать с шаблонами.Я видел некоторые посты здесь и т. Д., Но до сих пор не нашел ничего полезного.

Я вставляю базовый тестовый код для класса, с которым у меня проблемы, и основной.Остальная часть кода не будет мешать.

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';
}

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Нашел решение.Я публикую его здесь для тех, у кого такая же проблема.

QList - это шаблон класса в QT.Для тех, кто не использует QT, QList должен быть заменен чем-то вроде этого: "typedef std :: list list; list list_of_objects."

Вот оно:

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;

/ Теперь можно связывать разные объекты класса с разными индексами.Например: проверка по индексу 0, проверка 2 по индексу 1 ... и т. Д. /

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

    return a.exec();
}

Спасибо за помощь.

0 голосов
/ 23 февраля 2019

Вы не можете использовать T внутри Command, поскольку это не имя типа (кроме typedef).

Command должен быть шаблоном класса.

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';
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...