Название | Обратные вызовы в C++ |
---|---|
Автор произведения | Виталий Евгеньевич Ткаченко |
Жанр | Программирование |
Серия | |
Издательство | Программирование |
Год выпуска | 2020 |
isbn |
Рис. 5. Просмотр элементов с помощью обратных вызовов
1.2.4. Уведомление о событиях
Представим, что мы в системе запустили таймер, и нам нужно получить уведомление о срабатывании таймера. Самое простое решение – в процессе выполнения опрашивать таймер и анализировать, не истекло ли время. Как часто нужно делать опрос? Слишком часто – теряется производительность, слишком редко – теряется точность. Кроме того, приходится постоянно в определенных участках кода вставлять вызов опроса. Учитывая, что в программе могут работать несколько потоков, опрашивать таймер они будут с разной частотой, и каждый поток обнаружит срабатывание таймера в разное время.
Простое и эффективное решение указанных проблем представлено на Рис. 6. Код, обрабатывающий срабатывание таймера, упаковывается в отдельный компонент. Когда запускается таймер, этот компонент как аргумент передается таймеру, и когда таймер сработает, через сохраненный аргумент будет вызван код обработки. По такому же принципу можно организовать асинхронный ввод-вывод, обработку прерываний и т. п.
Рис. 6. Уведомление о срабатывании таймера с помощью обратного вызова
Итак, мы рассмотрели типовые задачи, в которых используются обратные вызовы. Как видим, подставляя соответствующие аргументы, можно запускать на выполнение различные участки программного кода. Отсюда можно сделать вывод, что обратные вызовы целесообразно использовать в случаях, когда требуется динамическая модификация поведения программы во время выполнения.
1.3. Модель обратных вызовов
1.3.1. Определения и термины
Модель обратных вызовов изображена на Рис. 7. Структурно она состоит из двух частей: исполнитель и инициатор.
Исполнитель – это компонент, в который упаковывается код обратного вызова (исполняемый код). Исполнитель также содержит контекст, который представляет собой совокупность данных, влияющих на поведение исполняемого кода.
Инициатор – это компонент, который осуществляет обратный вызов. Перед началом работы выполняется настройка, при которой исполнитель как аргумент вместе с контекстом сохраняются в инициаторе. Затем инициатор запускается, и в нужный момент, используя хранимый аргумент, он делает вызов исполняемого кода. В качестве входных параметров в этот код передается сохраненный контекст и информация вызова, которая представляет собой значения, формируемые инициатором.
Рис. 7. Модель обратных вызовов
Дадим формальные определения используемых терминов.
Исполнитель: компонент, который реализует исполняемый код обратного вызова.
Инициатор: компонент, который осуществляет обратный вызов.
Аргумент: хранимая точка входа в код обратного вызова.
Настройка: