Функция за обратно извикване е функция, която е аргумент, а не параметър, в друга функция. Другата функция може да се нарече основна функция. Така че са включени две функции: основната функция и самата функция за обратно извикване. В списъка с параметри на главната функция присъства декларацията на функцията за обратно извикване без нейната дефиниция, точно както присъстват декларациите на обекти без присвояване. Главната функция се извиква с аргументи (в 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: "<
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<