Функция обратного вызова - это функция, которая является аргументом, а не параметром в другой функции. Вторую функцию можно назвать основной функцией. Итак, задействованы две функции: основная функция и сама функция обратного вызова. В списке параметров основной функции присутствует объявление функции обратного вызова без ее определения, как и объявления объекта без присваивания. Основная функция вызывается с аргументами (в main ()). Одним из аргументов в вызове основной функции является эффективное определение функции обратного вызова. В C ++ этот аргумент является ссылкой на определение функции обратного вызова; это не настоящее определение. Сама функция обратного вызова фактически вызывается в определении основной функции.
Базовая функция обратного вызова в C ++ не гарантирует асинхронного поведения в программе. Асинхронное поведение - реальное преимущество схемы функции обратного вызова. В схеме асинхронной функции обратного вызова результат основной функции должен быть получен для программы до того, как будет получен результат функции обратного вызова. Это возможно сделать в C ++; однако в C ++ есть библиотека под названием future, чтобы гарантировать поведение схемы функции асинхронного обратного вызова.
В этой статье объясняется базовая схема функции обратного вызова. Многое на чистом C++. Что касается обратного вызова, также объясняется базовое поведение будущей библиотеки. Для понимания этой статьи необходимы базовые знания C ++ и его указателей.
Содержание статьи
- Схема базовой функции обратного вызова
- Синхронное поведение с функцией обратного вызова
- Асинхронное поведение с функцией обратного вызова
- Основы использования будущей библиотеки
- Заключение
Схема базовой функции обратного вызова
Схема функции обратного вызова требует основной функции и самой функции обратного вызова. Объявление функции обратного вызова является частью списка параметров основной функции. Определение функции обратного вызова указывается в вызове функции основной функции. Функция обратного вызова фактически вызывается в определении основной функции. Следующая программа иллюстрирует это:
#включатьиспользуя пространство имен std;
int принципалFn (char ch [], int (* ptr) (int))
int id1 = 1;
int id2 = 2;
int idr = (* ptr) (идентификатор2);
cout<<"principal function: "<
int cb (int ID)
cout<<"callback function"<<'\n';
вернуть идентификатор;
int main ()
интервал (* ptr) (интервал) = &cb;
char cha [] = "и";
mainFn (cha, cb);
возврат 0;
Результат:
функция обратного вызоваосновная функция: 1 и 2
Основная функция идентифицируется с помощью PrincipalFn (). Функция обратного вызова идентифицируется cb (). Функция обратного вызова определяется вне основной функции, но фактически вызывается внутри основной функции.
Обратите внимание на объявление функции обратного вызова в качестве параметра в списке параметров объявления основной функции. Объявление функции обратного вызова - «int (* ptr) (int)». Обратите внимание на выражение функции обратного вызова, как и на вызов функции, в определении основной функции; здесь передается любой аргумент для вызова функции обратного вызова. Заявление для этого вызова функции:
int idr = (* ptr) (идентификатор2);Где id2 - аргумент. ptr - это часть параметра, указатель, который будет связан со ссылкой на функцию обратного вызова в функции main ().
Обратите внимание на выражение:
интервал (* ptr) (интервал) = &cb;В функции main (), которая связывает объявление (без определения) функции обратного вызова с именем определения той же функции обратного вызова.
Основная функция вызывается в функции main () как:
mainFn (cha, cb);Где cha - строка, а cb - имя функции обратного вызова без каких-либо ее аргументов.
Синхронное поведение функции обратного вызова
Рассмотрим следующую программу:
#включатьиспользуя пространство имен std;
недействительный принципFn (void (* ptr) ())
cout<<"principal function"<<'\n';
(* ptr) ();
void cb ()
cout<<"callback function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
пусто (* ptr) () = &cb;
PrincipalFn (cb);
fn ();
возврат 0;
Результат:
основная функцияфункция обратного вызова
видимый
Здесь есть новая функция. Все, что делает новая функция, - это отображение вывода «видно». В функции main () вызывается основная функция, затем вызывается новая функция fn (). Выходные данные показывают, что был выполнен код для основной функции, затем был выполнен код для функции обратного вызова и, наконец, для функции fn () была выполнена. Это синхронное (однопоточное) поведение.
Если бы это было асинхронное поведение, когда три сегмента кода вызываются по порядку, может быть выполнен первый сегмент кода, за которым вместо этого следует выполнение третьего сегмента кода, прежде чем будет выполнен второй сегмент кода.
Что ж, функцию fn () можно вызвать из определения основной функции, а не из функции main (), следующим образом:
#включатьиспользуя пространство имен std;
void fn ()
cout<<"seen"<<'\n';
недействительный принципFn (void (* ptr) ())
cout<<"principal function"<<'\n';
fn ();
(* ptr) ();
void cb ()
cout<<"callback function"<<'\n';
int main ()
пусто (* ptr) () = &cb;
PrincipalFn (cb);
возврат 0;
Результат:
основная функциявидимый
функция обратного вызова
Это имитация асинхронного поведения. Это не асинхронное поведение. Это все еще синхронное поведение.
Кроме того, порядок выполнения сегмента кода основной функции и сегмента кода функции обратного вызова можно поменять местами в определении основной функции. Следующая программа иллюстрирует это:
#включатьиспользуя пространство имен std;
недействительный принципалFn (void (* ptr) ())
(* ptr) ();
cout<<"principal function"<<'\n';
void cb ()
cout<<"callback function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
пусто (* ptr) () = &cb;
PrincipalFn (cb);
fn ();
возврат 0;
Выход сейчас,
функция обратного вызоваосновная функция
видимый
Это тоже имитация асинхронного поведения. Это не асинхронное поведение. Это все еще синхронное поведение. Истинное асинхронное поведение может быть получено, как описано в следующем разделе, или с помощью библиотеки, в будущем.
Асинхронное поведение с функцией обратного вызова
Псевдокод для базовой схемы асинхронной функции обратного вызова:
тип вывода;type cb (тип вывода)
//заявления
тип PrincipalFn (тип ввода, тип cb (тип вывода))
//заявления
Обратите внимание на положение входных и выходных данных в разных местах псевдокода. Вход функции обратного вызова - это ее выход. Параметры основной функции - это входной параметр для общего кода и параметр для функции обратного вызова. С помощью этой схемы третья функция может быть выполнена (вызвана) в функции main () до того, как будет прочитан вывод функции обратного вызова (все еще в функции main ()). Следующий код иллюстрирует это:
#включатьиспользуя пространство имен std;
char * output;
void cb (char out [])
output = out;
void PrincipalFn (char input [], void (* ptr) (char [50]))
(* ptr) (ввод);
cout<<"principal function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
char input [] = "функция обратного вызова";
void (* ptr) (char []) = &cb;
PrincipalFn (ввод, cb);
fn ();
cout<