Функція зворотного виклику - це функція, яка є аргументом, а не параметром, в іншій функції. Іншу функцію можна назвати основною функцією. Отже, задіяні дві функції: основна функція та сама функція зворотного виклику. У списку параметрів головної функції присутнє оголошення функції зворотного виклику без її визначення, як і оголошення об'єктів без призначення. Основна функція викликається з аргументами (в main ()). Одним з аргументів у виклику основної функції є ефективне визначення функції зворотного виклику. У C ++ цей аргумент є посиланням на визначення функції зворотного виклику; це не власне визначення. Сама функція зворотного виклику фактично викликається у визначенні головної функції.
Основна функція зворотного виклику в C ++ не гарантує асинхронну поведінку в програмі. Асинхронна поведінка є реальною перевагою схеми функції зворотного виклику. У схемі асинхронної функції зворотного виклику результат основної функції повинен бути отриманий для програми до отримання результату функції зворотного виклику. Це можна зробити на C ++; однак у C ++ є бібліотека майбутнього, що гарантує поведінку асинхронної схеми функцій зворотного виклику.
У цій статті пояснюється основна схема функцій зворотного виклику. Багато це з чистим C++. Що стосується зворотного виклику, також пояснюється основна поведінка майбутньої бібліотеки. Для розуміння цієї статті необхідні базові знання C ++ та його покажчиків.
Зміст статті
- Схема основних функцій зворотного виклику
- Синхронна поведінка з функцією зворотного виклику
- Асинхронна поведінка з функцією зворотного виклику
- Основне використання майбутньої бібліотеки
- Висновок
Схема основних функцій зворотного виклику
Схема функції зворотного виклику потребує головної функції та самої функції зворотного дзвінка. Оголошення функції зворотного виклику є частиною списку параметрів основної функції. Визначення функції зворотного виклику вказується у виклику функції головної функції. Функція зворотного виклику фактично викликається у визначенні головної функції. Наступна програма це ілюструє:
#включативикористання простору імен std;
int principalFn (char ch [], int (* ptr) (int))
int id1 = 1;
int id2 = 2;
int idr = (* ptr) (id2);
кут<<"principal function: "<
int cb (int iden)
кут<<"callback function"<<'\n';
повернути іден;
int main ()
int (* ptr) (int) = &cb;
char cha [] = "та";
основнийFn (ча, cb);
повернути 0;
Результат:
функція зворотного дзвінкаосновна функція: 1 і 2
Основна функція ідентифікується principalFn (). Функція зворотного виклику визначається cb (). Функція зворотного виклику визначається поза основною функцією, але насправді викликається в рамках головної функції.
Зверніть увагу на декларацію функції зворотного виклику як параметр у списку параметрів декларації основної функції. Оголошення функції зворотного виклику - “int (* ptr) (int)”. Зверніть увагу на вираз функції зворотного виклику, як виклик функції, у визначенні головної функції; будь-який аргумент для виклику функції зворотного виклику передається туди. Оператор для цього виклику функції:
int idr = (* ptr) (id2);Де id2 - аргумент. ptr є частиною параметра, покажчиком, який буде пов'язаний з посиланням на функцію зворотного виклику у функції main ().
Зверніть увагу на вираз:
int (* ptr) (int) = &cb;У функції main (), яка пов'язує оголошення (без визначення) функції зворотного виклику з назвою визначення тієї самої функції зворотного виклику.
Основна функція у функції main () називається як:
основнийFn (ча, cb);Де cha - це рядок, а cb - це назва функції зворотного виклику без будь-якого аргументу.
Синхронна поведінка функції зворотного виклику
Розглянемо таку програму:
#включативикористання простору імен std;
void principalFn (void (* ptr) ())
кут<<"principal function"<<'\n';
(* ptr) ();
void cb ()
кут<<"callback function"<<'\n';
void fn ()
кут<<"seen"<<'\n';
int main ()
void (* ptr) () = &cb;
основнийFn (cb);
fn ();
повернути 0;
Результат:
головна функціяфункція зворотного дзвінка
бачили
Тут є нова функція. Все, що робить нова функція, - це відображення результату, "побаченого". У функції main () викликається основна функція, потім викликається нова функція fn (). Вихідні дані показують, що код для основної функції був виконаний, потім для функції зворотного виклику і, нарешті, для функції fn () було виконано. Це синхронна (однопоточна) поведінка.
Якби це була асинхронна поведінка, коли три сегменти коду викликаються в порядку, перший сегмент коду може бути виконаний, а замість нього виконується третій сегмент коду, перш ніж виконати другий сегмент коду.
Ну, функцію fn () можна викликати з визначення головної функції, а не зсередини функції main (), як показано нижче:
#включативикористання простору імен std;
void fn ()
кут<<"seen"<<'\n';
void principalFn (void (* ptr) ())
кут<<"principal function"<<'\n';
fn ();
(* ptr) ();
void cb ()
кут<<"callback function"<<'\n';
int main ()
void (* ptr) () = &cb;
основнийFn (cb);
повернути 0;
Результат:
головна функціябачили
функція зворотного дзвінка
Це імітація асинхронної поведінки. Це не асинхронна поведінка. Це все ще синхронна поведінка.
Крім того, порядок виконання сегмента коду основної функції та сегмента коду функції зворотного виклику можна поміняти місцями у визначенні головної функції. Наступна програма це ілюструє:
#включативикористання простору імен std;
void principalFn (void (* ptr) ())
(* ptr) ();
кут<<"principal function"<<'\n';
void cb ()
кут<<"callback function"<<'\n';
void fn ()
кут<<"seen"<<'\n';
int main ()
void (* ptr) () = &cb;
основнийFn (cb);
fn ();
повернути 0;
Вихід зараз,
функція зворотного дзвінкаголовна функція
бачили
Це також імітація асинхронної поведінки. Це не асинхронна поведінка. Це все ще синхронна поведінка. Справжню асинхронну поведінку можна отримати, як пояснюється в наступному розділі, або в бібліотеці майбутнього.
Асинхронна поведінка з функцією зворотного виклику
Псевдокодом для базової схеми асинхронних функцій зворотного виклику є:
тип виводу;тип cb (вивід типу)
// висловлювання
тип principalFn (тип вводу, тип cb (тип виводу))
// висловлювання
Зверніть увагу на позиції вхідних та вихідних даних у різних місцях псевдокоду. Вхідні дані функції зворотного виклику - це її вихідні дані. Параметри головної функції є вхідним параметром загального коду та параметром функції зворотного виклику. За цією схемою третя функція може бути виконана (викликана) у функції main () перед тим, як буде прочитано вихід функції зворотного виклику (як і раніше у функції main ()). Наступний код ілюструє це:
#включативикористання простору імен std;
char * вихід;
void cb (char out [])
вихід = вихід;
void principalFn (char input [], void (* ptr) (char [50]))
(* ptr) (введення);
кут<<"principal function"<<'\n';
void fn ()
кут<<"seen"<<'\n';
int main ()
char input [] = "функція зворотного виклику";
void (* ptr) (char []) = &cb;
principalFn (вхід, cb);
fn ();
кут<