Callback-функции

Callback-функции (функции обратного вызова) — это функции, передаваемые в качестве аргументов другим функциям и вызываемые при наступлении определённых событий.

Основные концепции callback-функций

Что такое callback?

Callback — это:

  • Функция, передаваемая в другую функцию как параметр

  • Механизм обратного вызова при наступлении события

  • Альтернатива полиморфизму в процедурном программировании

Где применяются callback-и?
  • Обработка событий (GUI, игры)

  • Асинхронные операции (сетевое программирование)

  • Алгоритмы с пользовательской логикой (сортировка, поиск)

  • Механизмы подписки и уведомлений


Реализация callback-ов

Указатели на функции (C-стиль):
// Тип для callback: void(int) typedef void (*CallbackType)(int); void processData(int value, CallbackType callback) { // Какая-то обработка callback(value * 2); // Вызов callback } void printResult(int result) { cout << "Result: " << result << endl; } int main() { processData(5, printResult); // Result: 10 }
Пояснение:
  1. typedef void (*CallbackType)(int)

    • Создаём тип для указателя на функцию, которая принимает int и возвращает void

    • Аналогично: using CallbackType = void(*)(int)

  2. Функция processData

    • Принимает число и callback-функцию

    • Умножает число на 2 и передаёт результат в callback

  3. Функция printResult

    • Просто выводит полученное значение

    • Это и есть наша callback-функция

  4. Вызов в main

    • Передаём printResult как callback

    • Функция processData вызывает её с результатом 10 (5*2)


std::function (современный C++): Более гибкий и безопасный способ:
#include <functional> void processData(int value, std::function<void(int)> callback) { callback(value * 2); } int main() { processData(5, [](int result) { cout << "Lambda result: " << result << endl; }); }
Пояснение:
  1. std::function<void(int)>

    • Универсальный контейнер для любых вызываемых объектов (функции, лямбды, функторы)

    • Принимает int, возвращает void

  2. Лямбда-функция

    • [](int result) { ... } — анонимная функция, захватывающая ничего ([])

    • Выводит полученный результат

  3. Преимущества перед C-стилем

    • Безопаснее (нет сырых указателей)

    • Поддерживает лямбды с захватом переменных

    • Более читаемый синтаксис


Функциональные объекты (функторы):
struct Callback { void operator()(int x) const { cout << "Functor: " << x << endl; } }; void process(int x, const Callback& cb) { cb(x); } int main() { process(10, Callback{}); // Functor: 10 }
Пояснение:
  1. struct Callback

    • Создаем структуру с именем Callback (можно использовать и class)

    • В C++ структуры и классы почти идентичны, разница только в дефолтной видимости (у struct - public)

  2. void operator()(int x) const

    • Перегружаем оператор вызова функции ()

    • Позволяет использовать объект как функцию

    • Принимает целочисленный параметр x

    • const означает, что метод не изменяет состояние объекта

  3. Тело оператора

    • Просто выводит полученное значение в формате: "Functor: x"

  4. Параметры:

    • int x - значение для обработки

    • const Callback& cb - принимаем функтор по константной ссылке (оптимально для передачи объектов)

  5. Вызов cb(x)

    • Хотя cb - это объект, благодаря перегруженному operator() мы можем вызывать его как функцию

    • Эквивалентно cb.operator()(x), но записывается короче


Производительность и оптимизация

Сравнение подходов
Метод Гибкость Производительность Безопасность
Указатели на функции Низкая Высокая Низкая
std::function Высокая Средняя Высокая
Функторы Средняя Высокая Высокая

Когда что использовать?

  • Указатели на функции: Когда нужна максимальная производительность и простота

  • std::function: В большинстве случаев, особенно с лямбдами

  • Функторы: Когда нужно сохранять сложное состояние

Callback-функции — это мощный механизм, который позволяет:

  • Создавать гибкие и расширяемые системы

  • Реализовывать асинхронную логику

  • Разрабатывать модульные компоненты


Комментарии

Добавить комментарий

Чтобы оставить комменатрий необходимо Авторизоваться