C ++

Функція зворотного виклику в C ++

Функція зворотного виклику в C ++

Функція зворотного виклику - це функція, яка є аргументом, а не параметром, в іншій функції. Іншу функцію можна назвати основною функцією. Отже, задіяні дві функції: основна функція та сама функція зворотного виклику. У списку параметрів головної функції присутнє оголошення функції зворотного виклику без її визначення, як і оголошення об'єктів без призначення. Основна функція викликається з аргументами (в 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: "<повернути id1;

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 ();
кут<повернути 0;

Вихід програми:

головна функція
бачили
функція зворотного дзвінка

У цьому конкретному коді вихідний та вхідний вихідні дані бувають однаковими. Результат третього виклику функції у функції main () відображався перед результатом функції зворотного виклику. Функція зворотного виклику виконується, закінчується та присвоює свій результат (значення) змінній, що виводить, що дозволяє програмі продовжувати роботу без її втручання. У функції main () висновок функції зворотного виклику використовувався (читався та відображався), коли це було потрібно, що призвело до асинхронної поведінки для всієї схеми.

Це однопотоковий спосіб отримати функцію зворотного виклику асинхронної поведінки з чистим C++.

Основне використання майбутньої бібліотеки

Ідея асинхронної схеми функції зворотного виклику полягає в тому, що основна функція повертається до повернення функції зворотного виклику. Це було зроблено опосередковано, ефективно, у наведеному вище коді.

Зверніть увагу на наведеному вище коді, що функція зворотного виклику отримує основний вхід для коду і виробляє основний вихідний код. Бібліотека C ++, майбутня, має функцію, яка називається sync (). Першим аргументом цієї функції є посилання на функцію зворотного виклику; другий аргумент - це вхід до функції зворотного виклику. Функція sync () повертається, не чекаючи завершення функції зворотного виклику, але дозволяє завершити функцію зворотного виклику. Це забезпечує асинхронну поведінку. Поки функція зворотного виклику продовжує виконуватися, оскільки функція sync () вже повернулася, оператори під нею продовжують виконуватися. Це як ідеальна асинхронна поведінка.

Вищевказана програма була переписана нижче з урахуванням майбутньої бібліотеки та її функції sync ():

#включати
#включати
#включати
використання простору імен std;
майбутнє вихід;
рядок cb (рядок stri)

зворотний стри;

void principalFn (рядок)

вихід = асинхронізація (cb, вхід);
кут<<"principal function"<<'\n';

void fn ()

кут<<"seen"<<'\n';

int main ()

рядок введення = рядок ("функція зворотного виклику");
principalFn (вхід);
fn ();
рядок ret = вивід.get (); // чекає повернення зворотного виклику, якщо це необхідно
кут<повернути 0;

Функція sync () нарешті зберігає вихідні дані функції зворотного виклику у майбутньому об’єкті. Очікуваний результат можна отримати у функції main (), використовуючи функцію-член get () майбутнього об'єкта.

Висновок

Функція зворотного виклику - це функція, яка є аргументом, а не параметром, в іншій функції. Схема функції зворотного виклику потребує головної функції та самої функції зворотного дзвінка. Оголошення функції зворотного виклику є частиною списку параметрів основної функції. Визначення функції зворотного виклику вказується у виклику функції головної функції (у main ()). Функція зворотного виклику фактично викликається у визначенні головної функції.

Схема функції зворотного виклику не обов'язково асинхронна. Щоб бути впевненим, що схема функції зворотного виклику є асинхронною, зробіть основний вхід в код, вхід у функцію зворотного виклику; зробити основний вивід коду, вихід функції зворотного виклику; зберігати вихідні дані функції зворотного виклику у змінній або структурі даних. У функції main () після виклику основної функції виконайте інші оператори програми. Коли потрібен вивід функції зворотного виклику, у функції main () використовуйте (читайте та відображайте) її тут же.

Middle mouse button not working in Windows 10
The middle mouse button helps you scroll through long webpages and screens with a lot of data. If that stops, well you will end up using the keyboard ...
How to change Left & Right mouse buttons on Windows 10 PC
It's quite a norm that all computer mouse devices are ergonomically designed for right-handed users. But there are mouse devices available which are s...
Emulate Mouse clicks by hovering using Clickless Mouse in Windows 10
Using a mouse or keyboard in the wrong posture of excessive usage can result in a lot of health issues, including strain, carpal tunnel syndrome, and ...