C ++

Функция за обратно извикване в C ++

Функция за обратно извикване в C ++

Функция за обратно извикване е функция, която е аргумент, а не параметър, в друга функция. Другата функция може да се нарече основна функция. Така че са включени две функции: основната функция и самата функция за обратно извикване. В списъка с параметри на главната функция присъства декларацията на функцията за обратно извикване без нейната дефиниция, точно както присъстват декларациите на обекти без присвояване. Главната функция се извиква с аргументи (в main ()). Един от аргументите в извикването на основната функция е ефективната дефиниция на функцията за обратно извикване. В C ++ този аргумент е препратка към дефиницията на функцията за обратно извикване; не е действителното определение. Самата функция за обратно извикване всъщност се извиква в рамките на дефиницията на основната функция.

Основната функция за обратно извикване в C ++ не гарантира асинхронно поведение в програма.  Асинхронното поведение е реалната полза от схемата на функцията за обратно извикване. В схемата на асинхронна функция за обратно извикване, резултатът от основната функция трябва да бъде получен за програмата, преди да бъде получен резултатът от функцията за обратно извикване. Възможно е да направите това в C ++; обаче C ++ има библиотека, наречена бъдеще, за да гарантира поведението на асинхронната схема на функцията за обратно извикване.

Тази статия обяснява основната схема на функцията за обратно извикване. Много от тях са с чист С++. Що се отнася до обратното обаждане, също е обяснено основното поведение на бъдещата библиотека. Основните познания за C ++ и неговите указатели са необходими за разбирането на тази статия.

Съдържание на статията

Схема на основната функция за обратно извикване

Схемата на функцията за обратно извикване се нуждае от основна функция и от самата функция за обратно извикване. Декларацията на функцията за обратно извикване е част от списъка с параметри на основната функция. Дефиницията на функцията за обратно извикване е посочена в извикването на функцията на основната функция. Функцията за обратно извикване всъщност се извиква в рамките на дефиницията на основната функция. Следващата програма илюстрира това:

#include
използване на пространство от имена std;
int principalFn (char ch [], int (* ptr) (int))

int id1 = 1;
int id2 = 2;
int idr = (* ptr) (id2);
Cout<<"principal function: "<връщане id1;

int cb (int iden)

Cout<<"callback function"<<'\n';
връщане iden;

int main ()

int (* ptr) (int) = &cb;
char cha [] = "и";
главенFn (cha, cb);
връщане 0;

Резултатът е:

функция за обратно извикване
основна функция: 1 и 2

Главната функция се идентифицира от principalFn (). Функцията за обратно извикване се идентифицира чрез cb (). Функцията за обратно извикване се дефинира извън основната функция, но всъщност се извиква в рамките на основната функция.

Обърнете внимание на декларацията на функцията за обратно извикване като параметър в списъка с параметри на декларацията на основната функция. Декларацията на функцията за обратно извикване е „int (* ptr) (int)“. Обърнете внимание на израза на функцията за обратно извикване, като повикване на функция, в дефиницията на основната функция; там се предава всеки аргумент за повикване на функцията за обратно извикване. Изявлението за това извикване на функция е:

int idr = (* ptr) (id2);

Където id2 е аргумент. ptr е част от параметъра, указател, който ще бъде свързан с препратката към функцията за обратно извикване във функцията main ().

Обърнете внимание на израза:

int (* ptr) (int) = &cb;

Във функцията main (), която свързва декларацията (без дефиниция) на функцията за обратно извикване с името на дефиницията на същата функция за обратно извикване.

Главната функция се нарича във функцията main () като:

главенFn (cha, cb);

Където cha е низ, а cb е името на функцията за обратно извикване без никакъв аргумент.

Синхронно поведение на функцията за обратно извикване

Обмислете следната програма:

#include
използване на пространство от имена std;
void principalFn (void (* ptr) ())

Cout<<"principal function"<<'\n';
(* ptr) ();

празно cb ()

Cout<<"callback function"<<'\n';

void fn ()

Cout<<"seen"<<'\n';

int main ()

void (* ptr) () = &cb;
главенFn (cb);
fn ();
връщане 0;

Резултатът е:

основна функция
функция за обратно извикване
видяно

Тук има нова функция. Всичко, което прави новата функция, е да показва изхода, "видян". Във функцията main () се извиква основната функция, след което се извиква новата функция fn (). Резултатът показва, че е изпълнен кодът за основната функция, след това този за функцията за обратно извикване и накрая, че за функцията fn () е изпълнена. Това е синхронно (еднонишко) поведение.

Ако това беше асинхронно поведение, когато три кодови сегмента са изредени по ред, първият кодов сегмент може да бъде изпълнен, последван от изпълнението на третия кодов сегмент, преди да бъде изпълнен вторият кодов сегмент.

Е, функцията fn () може да бъде извикана от дефиницията на основната функция, вместо от функцията main (), както следва:

#include
използване на пространство от имена std;
void fn ()

Cout<<"seen"<<'\n';

void principalFn (void (* ptr) ())

Cout<<"principal function"<<'\n';
fn ();
(* ptr) ();

празно cb ()

Cout<<"callback function"<<'\n';

int main ()

void (* ptr) () = &cb;
главенFn (cb);
връщане 0;

Резултатът е:

основна функция
видяно
функция за обратно извикване

Това е имитация на асинхронно поведение. Това не е асинхронно поведение. Все още е синхронно поведение.

Също така, редът на изпълнение на кодовия сегмент на основната функция и кодовият сегмент на функцията за обратно извикване могат да бъдат заменени в дефиницията на основната функция. Следващата програма илюстрира това:

#include
използване на пространство от имена std;
 
void principalFn (void (* ptr) ())

(* ptr) ();
Cout<<"principal function"<<'\n';

празно cb ()

Cout<<"callback function"<<'\n';

void fn ()

Cout<<"seen"<<'\n';

int main ()

void (* ptr) () = &cb;
главенFn (cb);
fn ();
връщане 0;

Резултатът е сега,

функция за обратно извикване
основна функция
видяно

Това също е имитация на асинхронно поведение. Това не е асинхронно поведение. Все още е синхронно поведение. Истинско асинхронно поведение може да се получи, както е обяснено в следващия раздел или с библиотеката, бъдеще.

Асинхронно поведение с функция за обратно извикване

Псевдокодът за основната схема на асинхронни функции за обратно извикване е:

тип изход;
тип cb (тип изход)

//изявления

тип principalFn (тип вход, тип cb (тип изход))

//изявления

Обърнете внимание на позициите на входните и изходните данни на различните места на псевдокода. Входът на функцията за обратно извикване е нейният изход. Параметрите на основната функция са входният параметър за общия код и параметърът за функцията за обратно извикване. С тази схема може да се изпълни (извика) трета функция във функцията main (), преди да се прочете изходът на функцията за обратно извикване (все още във функцията main ()). Следният код илюстрира това:

#include
използване на пространство от имена std;
char * изход;
void cb (извежда знака [])

изход = изход;

void principalFn (въвеждане на символи [], void (* ptr) (char [50]))

(* ptr) (вход);
Cout<<"principal function"<<'\n';

void fn ()

Cout<<"seen"<<'\n';

int main ()

char input [] = "функция за обратно извикване";
void (* ptr) (char []) = &cb;
главенFn (вход, cb);
fn ();
Cout<връщане 0;

Изходът на програмата е:

основна функция
видяно
функция за обратно извикване

В този конкретен код изходният и входният изходен сигнал се оказва еднакъв. Резултатът от третото извикване на функция във функцията main () е показан преди резултата от функцията за обратно извикване. Функцията за обратно извикване, изпълнена, завършена и присвоила своя резултат (стойност) на променливата, изход, позволявайки на програмата да продължи без нейната намеса. Във функцията main () изходът на функцията за обратно извикване се използва (чете и показва), когато е необходимо, което води до асинхронно поведение за цялата схема.

Това е еднонишков начин за получаване на асинхронно поведение на функцията за обратно извикване с чисто C++.

Основно използване на бъдещата библиотека

Идеята на схемата за асинхронна функция за обратно извикване е, че основната функция се връща преди функцията за обратно извикване да се върне. Това беше направено косвено, ефективно, в горния код.

Забележете от горния код, че функцията за обратно извикване получава основния вход за кода и произвежда основния изход за кода. Библиотеката на C ++, future, има функция, наречена sync (). Първият аргумент на тази функция е препратката към функцията за обратно извикване; вторият аргумент е входът към функцията за обратно извикване. Функцията sync () се връща, без да чака изпълнението на функцията за обратно извикване, но позволява функцията за обратно извикване да завърши. Това осигурява асинхронно поведение. Докато функцията за обратно извикване продължава да се изпълнява, тъй като функцията sync () вече се е върнала, операторите под нея продължават да се изпълняват. Това е като идеалното асинхронно поведение.

Горната програма е пренаписана по-долу, като се вземат предвид бъдещата библиотека и нейната функция sync ():

#include
#include
#include
използване на пространство от имена std;
бъдеще изход;
низ cb (низ стри)

връщане stri;

void principalFn (въвеждане на низ)

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

void fn ()

Cout<<"seen"<<'\n';

int main ()

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

Функцията sync () накрая съхранява изхода на функцията за обратно извикване в бъдещия обект. Очакваният изход може да се получи във функцията main (), като се използва функцията get () член на бъдещия обект.

Заключение

Функция за обратно извикване е функция, която е аргумент, а не параметър, в друга функция. Схемата на функцията за обратно извикване се нуждае от основна функция и от самата функция за обратно извикване. Декларацията на функцията за обратно извикване е част от списъка с параметри на основната функция. Дефиницията на функцията за обратно извикване е посочена в извикването на функцията на основната функция (в main ()). Функцията за обратно извикване всъщност се извиква в рамките на дефиницията на основната функция.

Схема на функция за обратно извикване не е непременно асинхронна. За да сте сигурни, че схемата на функцията за обратно извикване е асинхронна, направете основния вход към кода, входа към функцията за обратно повикване; направете основния изход на кода, изхода на функцията за обратно извикване; съхранява изхода на функцията за обратно извикване в променлива или структура от данни. Във функцията main (), след извикване на основната функция, изпълнете други изрази на приложението. Когато е необходим изходът на функцията за обратно извикване, във функцията main () го използвайте (четете и показвайте) там и след това.

Как да промените курсора на мишката и размера на курсора, цвета и схемата в Windows 10
Показалецът на мишката и курсорът в Windows 10 са много важни аспекти на операционната система. Това може да се каже и за други операционни системи, т...
Безплатни и игри с отворен код за разработване на Linux игри
Тази статия ще обхване списък с безплатни двигатели за игри с отворен код, които могат да се използват за разработване на 2D и 3D игри на Linux. Същес...
Урок Сянка на Tomb Raider за Linux
Shadow of the Tomb Raider е дванадесетото допълнение към поредицата Tomb Raider - франчайз за екшън-приключенска игра, създаден от Eidos Montreal. Игр...