Atšaukimo funkcija C ++

Callback Function C



Atskambinimo funkcija yra funkcija, kuri yra kitos funkcijos argumentas, o ne parametras. Kita funkcija gali būti vadinama pagrindine. Taigi yra dvi funkcijos: pagrindinė funkcija ir pati atšaukimo funkcija. Pagrindinės funkcijos parametrų sąraše yra atšaukimo funkcijos deklaracija be jos apibrėžimo, kaip ir objekto deklaracijos be priskyrimo. Pagrindinė funkcija iškviečiama argumentais (in main ()). Vienas iš pagrindinių funkcijų iškvietimo argumentų yra efektyvus atšaukimo funkcijos apibrėžimas. C ++ sistemoje šis argumentas yra nuoroda į atšaukimo funkcijos apibrėžimą; tai nėra tikrasis apibrėžimas. Pati atšaukimo funkcija iš tikrųjų vadinama pagrindinės funkcijos apibrėžimu.

Pagrindinė C ++ atgalinio ryšio funkcija negarantuoja asinchroninio elgesio programoje. Asinchroninis elgesys yra tikroji atgalinio ryšio funkcijos schemos nauda. Asinchroninės atgalinio ryšio funkcijos schemoje pagrindinės funkcijos rezultatas turėtų būti gautas programai prieš gaunant atgalinio ryšio funkcijos rezultatą. Tai galima padaryti naudojant C ++; tačiau „C ++“ turi biblioteką, pavadintą „ateitis“, kad užtikrintų asinchroninės atgalinio ryšio funkcijos schemos veikimą.







Šiame straipsnyje paaiškinama pagrindinė atgalinio ryšio funkcijos schema. Dauguma jų yra su grynu C ++. Kalbant apie atgalinį skambutį, taip pat paaiškinamas pagrindinis būsimos bibliotekos elgesys. Norint suprasti šį straipsnį, reikia pagrindinių žinių apie C ++ ir jo nuorodas.



Straipsnio turinys

Pagrindinė atgalinio ryšio funkcijų schema

Atšaukimo funkcijos schemai reikalinga pagrindinė funkcija ir pati atgalinio ryšio funkcija. Atšaukimo funkcijos deklaracija yra pagrindinės funkcijos parametrų sąrašo dalis. Atskambinimo funkcijos apibrėžimas nurodomas pagrindinės funkcijos funkcijos iškvietime. Atšaukimo funkcija iš tikrųjų vadinama pagrindinės funkcijos apibrėžimu. Toliau pateikta programa tai iliustruoja:



#įtraukti

naudojant vardų sritisvalandų;



tarptmainFn(anglisch[],tarpt (*ptr)(tarpt))

{

tarptid1= 1;

tarptid2= 2;

tarptpaprastai= (*ptr)(id2);

kaina<<'Pagrindinė funkcija:'<<id1<<''<<ch<<''<<paprastai<<' n';

grįžtiid1;

}


tarptcb(tarptidentif)

{

kaina<<„atgalinio ryšio funkcija“<<' n';

grįžtiidentif;

}


tarptpagrindinis()

{

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

anglisne[] = 'ir';

mainFn(tėvas, cb);



grįžti 0;

}

Išėjimas yra:





atgalinio ryšio funkcija

pagrindinė funkcija: 1 ir 2

Pagrindinė funkcija identifikuojama pagal principFF (). Atšaukimo funkcija identifikuojama cb (). Atšaukimo funkcija yra apibrėžta už pagrindinės funkcijos ribų, tačiau iš tikrųjų iškviečiama pagrindinėje funkcijoje.

Atkreipkite dėmesį į atšaukimo funkcijos deklaraciją kaip pagrindinės funkcijos deklaracijos parametrų sąrašo parametrą. Atšaukimo funkcijos deklaracija yra int (*ptr) (int). Atkreipkite dėmesį į atšaukimo funkcijos išraišką, kaip ir funkcijos iškvietimas, pagrindinės funkcijos apibrėžime; ten perduodami bet kokie atgalinio ryšio funkcijos iškvietimo argumentai. Šios funkcijos iškvietimo teiginys yra toks:



tarptpaprastai= (*ptr)(id2);

Kur id2 yra argumentas. ptr yra parametro dalis, rodyklė, kuri bus susieta su pagrindinės () funkcijos atšaukimo funkcijos nuoroda.

Atkreipkite dėmesį į išraišką:

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

Pagrindinėje () funkcijoje, kuri susieja atšaukimo funkcijos deklaraciją (be apibrėžties) su tos pačios atšaukimo funkcijos apibrėžimo pavadinimu.

Pagrindinė funkcija pagrindinėje () funkcijoje vadinama taip:

mainFn(tėvas, cb);

Kur cha yra eilutė, o cb - atšaukimo funkcijos pavadinimas be jo argumentų.

Sinchroninis atšaukimo funkcijos veikimas

Apsvarstykite šią programą:

#įtraukti

naudojant vardų sritisvalandų;



tuštumamainFn(tuštuma (*ptr)())

{

kaina<<'pagrindinė funkcija'<<' n';

(*ptr)();

}


tuštumacb()

{

kaina<<„atgalinio ryšio funkcija“<<' n';

}


tuštumafn()

{

kaina<<'mačiau'<<' n';

}


tarptpagrindinis()

{

tuštuma (*ptr)() = &cb;

mainFn(cb);

fn();



grįžti 0;

}

Išėjimas yra:

pagrindinė funkcija

atgalinio ryšio funkcija

matytas

Čia yra nauja funkcija. Visa naujoji funkcija yra parodyti išvestį, matytą. Pagrindinėje () funkcijoje vadinama pagrindinė funkcija, tada vadinama nauja funkcija fn (). Išvestis rodo, kad buvo įvykdytas pagrindinės funkcijos kodas, tada - atšaukimo funkcijos kodas ir galiausiai - fn () funkcija. Tai yra sinchroninis (viengubas) elgesys.

Jei tai būtų asinchroninis elgesys, kai trys kodo segmentai yra iškviečiami eilės tvarka, prieš vykdant antrąjį kodo segmentą gali būti vykdomas pirmasis kodo segmentas, o po to - trečiasis kodo segmentas.

Funkciją fn () galima iškviesti iš pagrindinės funkcijos apibrėžimo, o ne iš pagrindinės () funkcijos taip:

#įtraukti

naudojant vardų sritisvalandų;



tuštumafn()

{

kaina<<'mačiau'<<' n';

}


tuštumamainFn(tuštuma (*ptr)())

{

kaina<<'pagrindinė funkcija'<<' n';

fn();

(*ptr)();

}


tuštumacb()

{

kaina<<„atgalinio ryšio funkcija“<<' n';

}


tarptpagrindinis()

{

tuštuma (*ptr)() = &cb;

mainFn(cb);



grįžti 0;

}

Išėjimas yra:

pagrindinė funkcija

matytas

atgalinio ryšio funkcija

Tai asinchroninio elgesio imitacija. Tai nėra asinchroninis elgesys. Tai vis dar yra sinchroninis elgesys.

Taip pat pagrindinės funkcijos apibrėžime gali būti pakeista pagrindinės funkcijos kodo segmento vykdymo tvarka ir atgalinio ryšio funkcijos kodo segmentas. Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;



tuštumamainFn(tuštuma (*ptr)())

{

(*ptr)();

kaina<<'pagrindinė funkcija'<<' n';

}


tuštumacb()

{

kaina<<„atgalinio ryšio funkcija“<<' n';

}


tuštumafn()

{

kaina<<'mačiau'<<' n';

}


tarptpagrindinis()

{

tuštuma (*ptr)() = &cb;

mainFn(cb);

fn();



grįžti 0;

}

Išvestis dabar yra,

atgalinio ryšio funkcija

pagrindinė funkcija

matytas

Tai taip pat yra asinchroninio elgesio imitacija. Tai nėra asinchroninis elgesys. Tai vis dar yra sinchroninis elgesys. Tikras asinchroninis elgesys gali būti pasiektas, kaip paaiškinta kitame skyriuje arba ateityje su biblioteka.

Asinchroninis elgesys su atgalinio ryšio funkcija

Pagrindinės asinchroninės atgalinio ryšio funkcijos schemos pseudo kodas yra:

tipo išvestis;

tipas cb(tipo išvestis)

{

// teiginiai

}


tipas principinisFn(tipo įvestis, tipas cb(tipo išvestis))

{

// teiginiai

}

Atkreipkite dėmesį į įvesties ir išvesties duomenų pozicijas skirtingose ​​pseudo kodo vietose. Atgalinio skambučio įvestis yra jo išvestis. Pagrindinės funkcijos parametrai yra bendrojo kodo įvesties parametras ir atgalinio ryšio funkcijos parametras. Naudojant šią schemą, trečioji funkcija gali būti vykdoma (vadinama) pagrindinėje () funkcijoje prieš perskaitant atgalinio ryšio išvestį (vis dar veikia pagrindinėje () funkcijoje). Toliau pateiktas kodas tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

anglis *produkcija;


tuštumacb(anglisišeiti[])

{

produkcija=išeiti;

}



tuštumamainFn(anglisįvesties[],tuštuma (*ptr)(anglis[penkiasdešimt]))

{

(*ptr)(įvesties);

kaina<<'pagrindinė funkcija'<<' n';

}


tuštumafn()

{

kaina<<'mačiau'<<' n';

}


tarptpagrindinis()

{

anglisįvesties[] = „atgalinio ryšio funkcija“;

tuštuma (*ptr)(anglis[]) = &cb;

mainFn(įvestis, cb);

fn();

kaina<<produkcija<<' n';



grįžti 0;

}

Programos išvestis yra tokia:

pagrindinė funkcija

matytas

atgalinio ryšio funkcija

Šiuo konkrečiu kodu išvesties ir įvesties atskaitos taškas yra tas pats. Trečiojo pagrindinio () funkcijos iškvietimo rezultatas buvo rodomas prieš atšaukimo funkcijos rezultatą. Atšaukimo funkcija buvo įvykdyta, baigta ir priskirta jos rezultatas (vertė) kintamajam, išėjimui, leidžiančiam programai tęsti be trukdžių. Naudojant pagrindinę () funkciją, atgalinio ryšio funkcijos išvestis buvo naudojama (skaitoma ir rodoma), kai to reikėjo, o tai sukėlė asinchroninį elgesį visoje schemoje.

Tai yra viengubas būdas gauti asinchroninį atgalinio ryšio funkciją naudojant gryną C ++.

Pagrindinis būsimos bibliotekos naudojimas

Asinchroninės atšaukimo funkcijos schemos idėja yra ta, kad pagrindinė funkcija grįžta prieš grįžtamojo ryšio funkciją. Tai buvo padaryta netiesiogiai, efektyviai, aukščiau pateiktame kodekse.

Atkreipkite dėmesį į aukščiau pateiktą kodą, kad atgalinio ryšio funkcija gauna pagrindinį kodo įvestį ir sukuria pagrindinę kodo išvestį. Ateities „C ++“ biblioteka turi funkciją, vadinamą sinchronizavimu (). Pirmasis šios funkcijos argumentas yra atgalinio ryšio funkcijos nuoroda; antrasis argumentas yra atgalinio ryšio funkcijos įvestis. Funkcija sinchronizavimas () grįžta nelaukiant, kol bus baigta vykdyti atgalinio ryšio funkcija, tačiau leidžia užbaigti atgalinio ryšio funkciją. Tai užtikrina asinchroninį elgesį. Kol atšaukimo funkcija toliau vykdoma, kadangi sinchronizavimo () funkcija jau grįžo, toliau pateikiami teiginiai toliau vykdomi. Tai tarsi idealus asinchroninis elgesys.

Aukščiau pateikta programa buvo perrašyta žemiau, atsižvelgiant į būsimą biblioteką ir jos sinchronizavimo () funkciją:

#įtraukti

#įtraukti

#įtraukti

naudojant vardų sritisvalandų;

ateitį<eilutė>produkcija;

eilutė cb(styga stri)

{

grįžtistri;

}



tuštumamainFn(eilutės įvestis)

{

produkcija=asinchroninis(cb, įvestis);

kaina<<'pagrindinė funkcija'<<' n';

}


tuštumafn()

{

kaina<<'mačiau'<<' n';

}


tarptpagrindinis()

{

eilutės įvestis=eilutė(„atgalinio ryšio funkcija“);

mainFn(įvesties);

fn();

eilutė ret=produkcija.gauti(); // laukia, kol prireikus grįš atgalinis skambutis

kaina<<teisingai<<' n';



grįžti 0;

}

Funkcija sinchronizavimas () galiausiai išsaugo atšaukimo funkcijos išvestį į būsimą objektą. Tikėtiną išvestį galima gauti naudojant pagrindinę () funkciją, naudojant būsimo objekto funkciją get ().

Išvada

Atskambinimo funkcija yra funkcija, kuri yra kitos funkcijos argumentas, o ne parametras. Atšaukimo funkcijos schemai reikalinga pagrindinė funkcija ir pati atgalinio ryšio funkcija. Atšaukimo funkcijos deklaracija yra pagrindinės funkcijos parametrų sąrašo dalis. Atskambinimo funkcijos apibrėžimas nurodomas pagrindinės funkcijos funkcijos iškvietime (pagrindinėje ()). Atšaukimo funkcija iš tikrųjų vadinama pagrindinės funkcijos apibrėžimu.

Atšaukimo funkcijos schema nebūtinai yra asinchroninė. Norėdami būti tikri, kad atgalinio ryšio funkcijos schema yra asinchroninė, įveskite pagrindinį kodą, įveskite atgalinio ryšio funkciją; padaryti pagrindinį kodo išvestį, atgalinio ryšio funkcijos išvestį; išsaugoti atgalinio ryšio funkcijos išvestį kintamajame arba duomenų struktūroje. Pagrindinėje () funkcijoje, iškvietę pagrindinę funkciją, vykdykite kitus programos pareiškimus. Kai reikia atgalinio ryšio funkcijos išvesties, pagrindinėje () funkcijoje naudokite (skaitykite ir rodykite) ją ten ir tada.