Tagasihelistamise funktsioon C ++ keeles

Callback Function C



Tagasihelistamisfunktsioon on funktsioon, mis on teise funktsiooni argument, mitte parameeter. Teist funktsiooni võib nimetada põhifunktsiooniks. Seega on tegemist kahe funktsiooniga: põhifunktsioon ja tagasihelistamisfunktsioon ise. Põhifunktsiooni parameetrite loendis on tagasihelistamisfunktsiooni deklaratsioon ilma selle määratluseta olemas, nagu ka omistamiseta objektideklaratsioonid. Põhifunktsiooni kutsutakse argumentidega (in main ()). Üks põhifunktsiooni väljakutse argumente on tagasihelistamisfunktsiooni tõhus määratlus. C ++ puhul on see argument viide tagasihelistamisfunktsiooni määratlusele; see pole tegelik määratlus. Tagasihelistamisfunktsiooni ennast kutsutakse tegelikult põhifunktsiooni määratluse raames.

C ++ põhiline tagasihelistamisfunktsioon ei taga asünkroonset käitumist programmis. Asünkroonne käitumine on tagasihelistamisfunktsiooni skeemi tegelik kasu. Asünkroonse tagasihelistamise funktsiooni skeemis tuleks programmi jaoks põhifunktsiooni tulemus saada enne tagasihelistamisfunktsiooni tulemuse saamist. Seda on võimalik teha C ++; C ++ -l on aga teek nimega tulevik, et tagada asünkroonse tagasihelistamise funktsiooni skeemi käitumine.







Selles artiklis selgitatakse tagasihelistamise põhiskeemi. Suur osa sellest on puhta C ++ -ga. Tagasihelistamise osas selgitatakse ka tulevase raamatukogu põhikäitumist. Selle artikli mõistmiseks on vajalikud põhiteadmised C ++ ja selle viitade kohta.



Artikli sisu

Tagasihelistamise põhiskeem

Tagasihelistamisfunktsiooni skeem vajab põhifunktsiooni ja tagasihelistamisfunktsiooni ennast. Tagasihelistamisfunktsiooni deklaratsioon on osa põhifunktsiooni parameetrite loendist. Tagasihelistamisfunktsiooni määratlus on näidatud põhifunktsiooni funktsioonikutses. Tagasihelistamisfunktsiooni nimetatakse tegelikult põhifunktsiooni määratluse raames. Seda illustreerib järgmine programm:



#kaasake

kasutades nimeruumtundi;



intmainFn(süsich[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

inttavaliselt= (*ptr)(id2);

maksma<<'põhifunktsioon:'<<id1<<''<<ch<<''<<tavaliselt<<' n';

tagasiid1;

}


intcb(intident)

{

maksma<<'tagasihelistamise funktsioon'<<' n';

tagasiident;

}


intpeamine()

{

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

süsiei[] = 'ja';

mainFn(isa, cb);



tagasi 0;

}

Väljund on:





tagasihelistamise funktsioon

põhifunktsioon: 1 ja 2

Põhifunktsiooni tuvastab mainFF (). Tagasihelistamisfunktsiooni tähistab cb (). Tagasihelistamisfunktsioon on määratletud väljaspool põhifunktsiooni, kuid tegelikult kutsutakse seda põhifunktsiooni piires.

Pange tähele tagasihelistamisfunktsiooni deklaratsiooni parameetrina põhifunktsiooni deklaratsiooni parameetrite loendis. Tagasihelistamisfunktsiooni deklaratsioon on int (*ptr) (int). Märkige põhifunktsiooni määratluses tagasihelistamisfunktsiooni avaldis, nagu funktsioonikõne; seal edastatakse kõik tagasihelistamisfunktsiooni kõne argumendid. Selle funktsiooni kõne avaldus on järgmine:



inttavaliselt= (*ptr)(id2);

Kus id2 on argument. ptr on osa parameetrist, osuti, mis lingitakse põhifunktsiooni () tagasihelistamisfunktsiooni viitega.

Pange tähele väljendit:

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

Põhifunktsioonis (), mis seob tagasihelistamisfunktsiooni deklaratsiooni (ilma määratluseta) sama tagasihelistamisfunktsiooni definitsiooni nimega.

Põhifunktsiooni nimetatakse põhifunktsioonis () järgmiselt:

mainFn(isa, cb);

Kus cha on string ja cb on tagasihelistamisfunktsiooni nimi ilma selle argumentideta.

Tagasihelistamisfunktsiooni sünkroonne käitumine

Mõelge järgmisele programmile:

#kaasake

kasutades nimeruumtundi;



tühinemainFn(tühine (*ptr)())

{

maksma<<'põhifunktsioon'<<' n';

(*ptr)();

}


tühinecb()

{

maksma<<'tagasihelistamise funktsioon'<<' n';

}


tühinefn()

{

maksma<<'nähtud'<<' n';

}


intpeamine()

{

tühine (*ptr)() = &cb;

mainFn(cb);

fn();



tagasi 0;

}

Väljund on:

põhifunktsioon

tagasihelistamise funktsioon

nähtud

Siin on uus funktsioon. Kõik uus funktsioon teeb, on väljundi kuvamine. Funktsioonis main () nimetatakse põhifunktsiooni, seejärel uut funktsiooni fn (). Väljund näitab, et põhifunktsiooni kood, seejärel tagasihelistamisfunktsiooni kood ja lõpuks fn () funktsioon täideti. See on sünkroonne (ühe lõimega) käitumine.

Kui tegemist oleks asünkroonse käitumisega, võib kolme koodisegmenti järjekorras kokku kutsudes täita esimese koodisegmendi, millele järgneb kolmanda koodisegmendi täitmine enne teise koodisegmendi täitmist.

Funktsiooni fn () saab kutsuda põhifunktsiooni definitsiooni seest, mitte põhifunktsiooni () seest, järgmiselt:

#kaasake

kasutades nimeruumtundi;



tühinefn()

{

maksma<<'nähtud'<<' n';

}


tühinemainFn(tühine (*ptr)())

{

maksma<<'põhifunktsioon'<<' n';

fn();

(*ptr)();

}


tühinecb()

{

maksma<<'tagasihelistamise funktsioon'<<' n';

}


intpeamine()

{

tühine (*ptr)() = &cb;

mainFn(cb);



tagasi 0;

}

Väljund on:

põhifunktsioon

nähtud

tagasihelistamise funktsioon

See on asünkroonse käitumise jäljendus. See pole asünkroonne käitumine. See on ikka sünkroonne käitumine.

Samuti saab põhifunktsiooni määratluses vahetada põhifunktsiooni koodisegmendi ja tagasihelistamisfunktsiooni koodisegmendi täitmise järjekorda. Seda illustreerib järgmine programm:

#kaasake

kasutades nimeruumtundi;



tühinemainFn(tühine (*ptr)())

{

(*ptr)();

maksma<<'põhifunktsioon'<<' n';

}


tühinecb()

{

maksma<<'tagasihelistamise funktsioon'<<' n';

}


tühinefn()

{

maksma<<'nähtud'<<' n';

}


intpeamine()

{

tühine (*ptr)() = &cb;

mainFn(cb);

fn();



tagasi 0;

}

Väljund on nüüd,

tagasihelistamise funktsioon

põhifunktsioon

nähtud

See on ka asünkroonse käitumise jäljendus. See pole asünkroonne käitumine. See on ikka sünkroonne käitumine. Tõelise asünkroonse käitumise saab saavutada, nagu on selgitatud järgmises osas või koos teekiga.

Asünkroonne käitumine tagasihelistamisfunktsiooniga

Põhilise asünkroonse tagasihelistamise funktsiooni skeemi pseudokood on järgmine:

tüüpi väljund;

tüüp cb(tüüpi väljund)

{

// avaldused

}


tüüp printsFn(tüüpi sisend, tüüp cb(tüüpi väljund))

{

// avaldused

}

Pange tähele sisend- ja väljundandmete asukohti pseudokoodi erinevates kohtades. Tagasihelistamisfunktsiooni sisend on selle väljund. Põhifunktsiooni parameetrid on üldkoodi sisendparameeter ja tagasihelistamisfunktsiooni parameeter. Selle skeemi korral saab põhifunktsioonis () käivitada (kutsuda) kolmanda funktsiooni enne tagasihelistamisfunktsiooni väljundi lugemist (endiselt põhifunktsioonis). Seda illustreerib järgmine kood:

#kaasake

kasutades nimeruumtundi;

süsi *väljund;


tühinecb(süsivälja[])

{

väljund=välja;

}



tühinemainFn(süsisisend[],tühine (*ptr)(süsi[viiskümmend]))

{

(*ptr)(sisend);

maksma<<'põhifunktsioon'<<' n';

}


tühinefn()

{

maksma<<'nähtud'<<' n';

}


intpeamine()

{

süsisisend[] = 'tagasihelistamise funktsioon';

tühine (*ptr)(süsi[]) = &cb;

mainFn(sisend, cb);

fn();

maksma<<väljund<<' n';



tagasi 0;

}

Programmi väljund on järgmine:

põhifunktsioon

nähtud

tagasihelistamise funktsioon

Selle konkreetse koodi puhul on väljund- ja sisend -tugipunkt sama. Põhifunktsiooni () kolmanda funktsioonikõne tulemus on kuvatud enne tagasihelistamisfunktsiooni tulemust. Tagasihelistamisfunktsioon käivitas, lõpetas ja määras selle tulemuse (väärtuse) muutujale, väljundile, võimaldades programmil ilma sekkumiseta jätkata. Põhifunktsioonis () kasutati tagasihelistamise funktsiooni väljundit (loeti ja kuvati), kui seda vajati, mis viis kogu skeemi asünkroonse käitumiseni.

See on ühe lõimega viis tagasihelistamisfunktsiooni asünkroonseks käitumiseks puhta C ++ abil.

Tulevase raamatukogu põhikasutus

Asünkroonse tagasihelistamise funktsiooni skeemi idee seisneb selles, et põhifunktsioon naaseb enne tagasihelistamisfunktsiooni naasmist. Seda tehti ülaltoodud koodis kaudselt ja tõhusalt.

Pange tähele ülaltoodud koodist, et tagasihelistamisfunktsioon võtab vastu koodi põhisisendi ja toodab koodi peamise väljundi. Tuleviku C ++ raamatukogul on funktsioon nimega sync (). Selle funktsiooni esimene argument on tagasihelistamisfunktsiooni viide; teine ​​argument on tagasihelistamisfunktsiooni sisend. Funktsioon sync () naaseb ootamata tagasihelistamisfunktsiooni täitmise lõppu, kuid võimaldab tagasihelistamisfunktsiooni lõpule viia. See tagab asünkroonse käitumise. Kuigi tagasihelistamisfunktsiooni täitmine jätkub, kuna funktsioon sync () on juba naasnud, jätkatakse selle all olevate avalduste täitmist. See on nagu ideaalne asünkroonne käitumine.

Ülaltoodud programm on allpool ümber kirjutatud, võttes arvesse tulevast raamatukogu ja selle sünkroonimise () funktsiooni:

#kaasake

#kaasake

#kaasake

kasutades nimeruumtundi;

tulevik<string>väljund;

string cb(string stri)

{

tagasistri;

}



tühinemainFn(stringi sisend)

{

väljund=asünkroon(cb, sisend);

maksma<<'põhifunktsioon'<<' n';

}


tühinefn()

{

maksma<<'nähtud'<<' n';

}


intpeamine()

{

stringi sisend=string('tagasihelistamise funktsioon');

mainFn(sisend);

fn();

string ret=väljund.saada(); // ootab vajadusel tagasihelistamist

maksma<<õige<<' n';



tagasi 0;

}

Funktsioon sync () salvestab lõpuks tagasihelistamisfunktsiooni väljundi tulevasse objekti. Oodatavat väljundit saab saada põhifunktsioonis (), kasutades tulevase objekti funktsiooni get ().

Järeldus

Tagasihelistamisfunktsioon on funktsioon, mis on teise funktsiooni argument, mitte parameeter. Tagasihelistamisfunktsiooni skeem vajab põhifunktsiooni ja tagasihelistamisfunktsiooni ennast. Tagasihelistamisfunktsiooni deklaratsioon on osa põhifunktsiooni parameetrite loendist. Tagasihelistamisfunktsiooni määratlus on näidatud põhifunktsiooni funktsioonikutses (põhis ()). Tagasihelistamisfunktsiooni nimetatakse tegelikult põhifunktsiooni määratluse raames.

Tagasihelistamisfunktsiooni skeem ei pruugi olla asünkroonne. Et olla kindel, et tagasihelistamisfunktsiooni skeem on asünkroonne, sisestage koodi põhisisend, tagasihelistamisfunktsiooni sisend; teha koodi peamine väljund, tagasihelistamisfunktsiooni väljund; salvestage tagasihelistamisfunktsiooni väljund muutujale või andmestruktuurile. Funktsioonis main () käivitage pärast põhifunktsiooni kutsumist rakenduse muud avaldused. Kui on vaja tagasihelistamisfunktsiooni väljundit, kasutage põhifunktsioonis () seda funktsiooni (lugemine ja kuvamine) seal ja siis.