C ++

Tagasihelistamisfunktsioon C ++ keeles

Tagasihelistamisfunktsioon C ++ keeles

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

Põhihelistaja funktsioon C ++ ei taga programmi asünkroonset käitumist.  Asünkroonne käitumine on tagasihelistamisfunktsioonide skeemi tegelik eelis. Asünkroonse tagasihelistamisfunktsiooni skeemis peaks programmi jaoks saama põhifunktsiooni tulemus enne tagasihelistamisfunktsiooni tulemuse saamist. Seda on võimalik teha C ++ keeles; asünkroonse tagasihelistamisfunktsiooni skeemi käitumise tagamiseks on C ++-l aga kogu, mida nimetatakse tulevikuks.

Selles artiklis selgitatakse tagasihelistamisfunktsioonide põhiskeemi. Suur osa sellest on puhta C-ga++. Mis puudutab tagasihelistamist, siis selgitatakse ka tulevase raamatukogu põhikäitumist. Selle artikli mõistmiseks on vaja põhiteadmisi C ++ ja selle viidete kohta.

Artikli sisu

Põhihelistamisfunktsioonide skeem

Tagasihelistamisfunktsioonide skeem vajab põhifunktsiooni ja tagasihelistamisfunktsioon ise. Tagasihelistamisfunktsiooni deklaratsioon on osa põhifunktsiooni parameetrite loendist. Tagasihelistamisfunktsiooni määratlus on näidatud põhifunktsiooni funktsioonikutses. Tagasihelistamisfunktsiooni nimetatakse tegelikult põhifunktsiooni määratluses. Järgmine programm illustreerib seda:

# kaasata
nimeruumi kasutamine std;
int peamineFn (char ch [], int (* ptr) (int))

int id1 = 1;
int id2 = 2;
int idr = (* ptr) (id2);
cout<<"principal function: "<tagastus id1;

int cb (int iden)

cout<<"callback function"<<'\n';
tagasiside iden;

int main ()

int (* ptr) (int) = &cb;
char cha [] = "ja";
peamineFn (cha, cb);
tagastama 0;

Väljund on:

tagasihelistamisfunktsioon
põhifunktsioon: 1 ja 2

Põhifunktsioon tuvastatakse peafn () abil. Tagasihelistamisfunktsiooni tuvastab cb (). Tagasihelistamisfunktsioon on määratletud väljaspool põhifunktsiooni, kuid tegelikult kutsutakse seda põhifunktsiooni piires.

Pange tähele tagasihelistamisfunktsiooni deklaratsioon parameetrina põhifunktsiooni deklaratsiooni parameetrite loendis. Tagasihelistamisfunktsiooni deklaratsioon on “int (* ptr) (int)”. Pange funktsiooni tagasihelistamise avaldis nagu funktsiooni väljakutse põhifunktsiooni määratlusse; sinna edastatakse mis tahes argument tagasihelistamisfunktsiooni väljakutse jaoks. Selle funktsioonikõne lause on:

int idr = (* ptr) (id2);

Kus id2 on argument. ptr on parameetri osa, osuti, mis on seotud peafunktsiooni () tagasihelistamisfunktsiooni viitega.

Pange tähele väljendit:

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

Funktsioonis main (), mis seob tagasihelistamisfunktsiooni deklaratsiooni (ilma määratluseta) sama tagasihelistamisfunktsiooni definitsiooni nimega.

Põhifunktsiooni nimetatakse main () funktsioonis järgmiselt:

peamineFn (cha, cb);

Kui cha on string ja cb on tagasihelistamisfunktsiooni nimi ilma selle argumendita.

Tagasihelistamisfunktsiooni sünkroonne käitumine

Mõelge järgmisele programmile:

# kaasata
nimeruumi kasutamine std;
void basicFn (void (* ptr) ())

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

kehtetu cb ()

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

tühine fn ()

cout<<"seen"<<'\n';

int main ()

tühine (* ptr) () = &cb;
peamineFn (cb);
fn ();
tagastama 0;

Väljund on:

põhifunktsioon
tagasihelistamisfunktsioon
nähtud

Siin on uus funktsioon. Uue funktsioonina kuvatakse väljund, "nähtud". Funktsioonis main () nimetatakse põhifunktsiooni, seejärel uut funktsiooni fn (). Väljund näitab, et põhifunktsiooni kood käivitati, seejärel tagasihelistamisfunktsiooni kood ja lõpuks fn () funktsiooni. See on sünkroonne (ühe keermega) käitumine.

Kui tegemist oleks asünkroonse käitumisega, võidakse kolme koodisegmendi järjestusse kutsumisel enne teise koodisegmendi käivitamist käivitada esimene koodisegment, millele järgneb kolmanda koodisegmendi käivitamine.

Noh, funktsiooni fn () saab kutsuda põhifunktsiooni määratluses, mitte funktsiooni main () järgi:

# kaasata
nimeruumi kasutamine std;
tühine fn ()

cout<<"seen"<<'\n';

void basicFn (void (* ptr) ())

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

kehtetu cb ()

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

int main ()

tühine (* ptr) () = &cb;
peamineFn (cb);
tagastama 0;

Väljund on:

põhifunktsioon
nähtud
tagasihelistamisfunktsioon

See on asünkroonse käitumise jäljendamine. See pole asünkroonne käitumine. See on ikkagi sünkroonne käitumine.

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

# kaasata
nimeruumi kasutamine std;
 
void basicFn (void (* ptr) ())

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

kehtetu cb ()

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

tühine fn ()

cout<<"seen"<<'\n';

int main ()

tühine (* ptr) () = &cb;
peamineFn (cb);
fn ();
tagastama 0;

Väljund on nüüd,

tagasihelistamisfunktsioon
põhifunktsioon
nähtud

See on ka asünkroonse käitumise jäljendamine. See pole asünkroonne käitumine. See on ikkagi sünkroonne käitumine. Tõelise asünkroonse käitumise võib saada järgmises jaotises selgitatuna või tuleviku teegiga.

Asünkroonne käitumine koos tagasihelistamisfunktsiooniga

Asünkroonse tagasihelistamise põhiskeemi pseudokood on:

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

// avaldused

type basicFn (tüübi sisend, tüüp cb (tüübi väljund))

// avaldused

Pange tähele sisend- ja väljundandmete asukohad pseudokoodi erinevates kohtades. Tagasihelistamisfunktsiooni sisend on selle väljund. Põhifunktsiooni parameetrid on üldkoodi sisendparameetrid ja tagasihelistamisfunktsiooni parameetrid. Selle skeemi abil saab funktsiooni main () funktsioonis käivitada (kutsuda) kolmanda funktsiooni enne tagasihelistamisfunktsiooni väljundi lugemist (endiselt põhifunktsioonis ()). Järgmine kood illustreerib seda:

# kaasata
nimeruumi kasutamine std;
char * väljund;
void cb (char out [])

väljund = välja;

void basicFn (char sisend [], void (* ptr) (char [50]))

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

tühine fn ()

cout<<"seen"<<'\n';

int main ()

char input [] = "tagasihelistamisfunktsioon";
tühine (* ptr) (char []) = &cb;
peamineFn (sisend, cb);
fn ();
cout<tagastama 0;

Programmi väljund on:

põhifunktsioon
nähtud
tagasihelistamisfunktsioon

Selles konkreetses koodis on väljund- ja sisendpunkt juhuslikult sama. Main () funktsiooni kolmanda funktsioonikõne tulemus on kuvatud enne tagasihelistamisfunktsiooni tulemust. Tagasihelistamisfunktsioon teostas, lõpetas ja määras oma tulemuse (väärtuse) muutujale output, võimaldades programmil ilma sekkumiseta jätkata. Funktsioonis main () kasutati tagasihelistamisfunktsiooni väljundit (loeti ja kuvati) vajadusel, mis viis kogu skeemi asünkroonse käitumiseni.

See on üheahelaline viis tagasihelistamisfunktsiooni asünkroonse käitumise saamiseks puhta C-ga++.

Tulevase raamatukogu põhikasutus

Asünkroonse tagasihelistamisfunktsiooni skeemi idee on see, et põhifunktsioon naaseb enne tagasihelistusfunktsiooni naasmist. Seda tehti kaudselt, tõhusalt ülaltoodud koodis.

Pange ülaltoodud koodilt tähele, et tagasihelistamisfunktsioon saab koodi peamise sisendi ja toodab koodi jaoks peamise väljundi. Tuleviku C ++ teegil 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 lubab tagasihelistamisfunktsiooni lõpule viia. See tagab asünkroonse käitumise. Kui tagasihelistamisfunktsioon jätkub, kuna funktsioon sync () on juba tagasi jõudnud, jätkavad selle all olevad väited. See on nagu ideaalne asünkroonne käitumine.

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

# kaasata
# kaasata
# kaasata
nimeruumi kasutamine std;
tulevik väljund;
string cb (stringi riba)

tagastusriba;

void basicFn (stringi sisend)

väljund = asünkroon (cb, sisend);
cout<<"principal function"<<'\n';

tühine fn ()

cout<<"seen"<<'\n';

int main ()

stringi sisend = string ("tagasihelistamisfunktsioon");
peamineFn (sisend);
fn ();
string ret = väljund.saada (); // ootab vajadusel tagasihelistamist
cout<tagastama 0;

Funktsioon sync () salvestab lõpuks tagasihelistamisfunktsiooni väljundi tulevasse objekti. Eeldatava väljundi saab funktsioonist main (), kasutades tulevase objekti funktsiooni get ().

Järeldus

Tagasihelistamisfunktsioon on funktsioon, mis on mõnes teises funktsioonis argument, mitte parameeter. Tagasihelistamisfunktsioonide skeem vajab põhifunktsiooni ja tagasihelistamisfunktsioon ise. Tagasihelistamisfunktsiooni deklaratsioon on osa põhifunktsiooni parameetrite loendist. Tagasihelistamisfunktsiooni määratlus on näidatud põhifunktsiooni funktsioonikutses (main ()). Tagasihelistamisfunktsiooni nimetatakse tegelikult põhifunktsiooni määratluses.

Tagasihelistamisfunktsioonide skeem ei ole tingimata asünkroonne. Tagasihelistamisfunktsiooni skeemi asünkroonsuse tagamiseks sisestage koodile peamine sisend, tagasihelistamisfunktsiooni sisend; teha koodi põhiväljund, tagasihelistamisfunktsiooni väljund; salvestage tagasihelistamisfunktsiooni väljund muutujas või andmestruktuuris. Funktsioonis main (), pärast põhifunktsiooni kutsumist, käivitage rakenduse muud laused. Kui vajate tagasihelistamisfunktsiooni väljundit, kasutage funktsiooni main () funktsioonis (loe ja kuva) seda seal ja siis.

Parimad Linuxi käsurea mängud
Käsurida pole Linuxi kasutamisel lihtsalt teie suurim liitlane - see võib olla ka meelelahutusallikas, sest saate seda kasutada paljude lõbusate mängu...
Parimad Linuxi mängupuldi kaardistamise rakendused
Kui teile meeldib mängida Linuxis mänge tavalise klaviatuuri ja hiire sisestussüsteemi asemel mängupuldiga, on teie jaoks mõned kasulikud rakendused. ...
Kasulikud tööriistad Linuxi mängijatele
Kui teile meeldib Linuxis mänge mängida, on tõenäoline, et olete mängukogemuse parandamiseks kasutanud selliseid rakendusi ja utiliite nagu Wine, Lutr...