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

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

СКАЧАТЬ для синхронного вызова с лямбда-выражением реализуется в виде шаблонной функции, параметром шаблона выступает тип аргумента. Подробно этот вопрос рассмотрен в п. 4.2.1.

      2.5.5. Преимущества и недостатки

      Преимущества и недостатки реализации обратных вызовов с помощью лямбда-выражения приведены в Табл. 6.

      Табл. 6. Преимущества и недостатки обратных вызовов с помощью лямбда-выражения.

      Гибкое управление контекстом. Возможность захвата переменных предоставляет простые и удобные средства изменения контекста. Изменяя состав захваченных переменных, мы легко можем добавлять значения, необходимые для контекста, при этом нет необходимости изменять код инициатора. Захватив указатель this, мы получаем доступ к содержимому класса, т. е. фактически лямбда-выражение превращается в «метод внутри метода» (см. пример в Листинг 22). Элегантно, не правда ли?

      Требует использования шаблонов. Использование шаблонов накладывает архитектурные ограничения на реализацию программных модулей. Это связанно с тем, что шаблоны не предполагают присутствие предварительно откомпилированного кода. Подробнее об этом мы будем говорить в соответствующей главе (4.7), посвященной ограничениям при использовании шаблонов.

Листинг 22. Лямбда-выражение с захватом указателя this

      class EventCounter

      {

      public:

        void AddEvent(unsigned int event)

        {

            callCounter_++;

            lastEvent_ = event;

        }

      private:

        unsigned int callCounter_ = 0;

        int lastEvent_ = 0;

      };

      class Executor

      {

      public:

        Executor(EventCounter* counter): counter_(counter)

        {

            auto lambda = [this](int eventID)

            {

                //It will be called by initiator

                counter_->AddEvent(eventID);

                processEvent(eventID);

            };

            //Setup lambda in initiator

        }

      private:

        EventCounter* counter_;

        void processEvent(int eventID) {/*Do something*/}

      };

      2.6. Итоги

      В C++ обратные вызовы могут быть реализованы с помощью следующих конструкций:

      • указатель на функцию;

      • указатель на статический метод класса;

      • указатель на метод-член класса;

      • функциональный объект;

      • лямбда-выражение.

      Каждая реализация имеет свои достоинства и недостатки. Так какую все-таки выбрать? Чтобы ответить на этот вопрос, необходимо выполнить сравнительный анализ.

      3. Сравнительный анализ реализаций

      3.1. Методологические подходы

      3.1.1. СКАЧАТЬ