Обратные вызовы в C++. Виталий Евгеньевич Ткаченко
Чтение книги онлайн.

Читать онлайн книгу Обратные вызовы в C++ - Виталий Евгеньевич Ткаченко страница 10

СКАЧАТЬ style="font-size:15px;">      class Initiator  // (2)

      {

      public:

        using ptr_callback_method = void(Executor::*)(int);  // (3)

        void setup(Executor* argCallbackClass, ptr_callback_method argCallbackMethod)    // (4)

        {

            ptrCallbackClass = argCallbackClass; ptrCallbackMethod = argCallbackMethod;  // (5)

        }

        void run()  // (6)

        {

            int eventID = 0;

            //Some actions

            (ptrCallbackClass->*ptrCallbackMethod)(eventID);  // (7)

        }

      private:

        Executor* ptrCallbackClass = nullptr;             // (8)

        ptr_callback_method ptrCallbackMethod = nullptr;  // (9)

      };

      В строке 1 делается предварительное объявление типа класса исполнителя. В строке 2 объявляется класс-инициатор, в строке 3 объявляется тип указателя для класса-исполнителя. В строке 4 объявляется функция для настройки указателей, соответствующие переменные (указатель на метод класса и указатель на экземпляр класса) объявлены в строках 8 и 9. В строке 6 объявлена функция запуска, внутри этой функции в строке 7 через соответствующий указатель производится вызов метода класса.

      2.3.3. Исполнитель

      Реализация исполнителя приведена в Листинг 11.

Листинг 11. Исполнитель с указателем на метод-член класса

      class Executor                       // (1)

      {

      public:

        void callbackHandler(int eventID)  // (2)

        {

            //It will be called by initiator

        }

      };

      int main()                                                 // (3)

      {

        Initiator initiator;                                     // (4)

        Executor executor;                                       // (5)

        initiator.setup(&executor, &Executor::callbackHandler);  // (6)

        initiator.run();                                         // (7)

      }

      В строке 1 объявляется класс-исполнитель. В строке 2 объявлен метод класса, который будет выполнять функцию обработчика обратного вызова. В указанный метод передается информация вызова (в нашем случае это eventID). В строке 3 объявлена основная функция, в которой осуществляются все необходимые операции. В строке 4 объявлен класс-инициатор, в строке 5 объявлен класс-исполнитель. В строке 6 осуществляется настройка обратного вызова, в строке 7 производится запуск инициатора.

      2.3.4. Управление контекстом

      Рассматриваемая реализация позволяет осуществлять управление контекстом тремя способами: настройка экземпляра класса-исполнителя, настройка указателя на метод, переопределение виртуальных функций. Это приводит к интересным эффектам.

      Пусть у нас будут объявления классов-исполнителей с наследованием, как показано в Листинг 12. Графически иерархия наследования изображена на Рис. 13.

Листинг 12. Классы-исполнители с наследованием

      class Executor

СКАЧАТЬ