C ++

Funkcija povratnog poziva u C ++

Funkcija povratnog poziva u C ++

Funkcija povratnog poziva je funkcija koja je argument, a ne parametar druge funkcije. Druga se funkcija može nazvati glavnom funkcijom. Dakle, uključene su dvije funkcije: glavna funkcija i sama funkcija povratnog poziva. Na popisu parametara glavne funkcije prisutna je deklaracija funkcije povratnog poziva bez njene definicije, baš kao što su prisutne deklaracije objekata bez dodjele. Glavna se funkcija poziva s argumentima (u main ()). Jedan od argumenata u pozivu glavne funkcije je učinkovita definicija funkcije povratnog poziva. U C ++-u je ovaj argument referenca na definiciju funkcije povratnog poziva; to nije stvarna definicija. Sama funkcija povratnog poziva zapravo se poziva unutar definicije glavne funkcije.

Osnovna funkcija povratnog poziva u C ++-u ne jamči asinkrono ponašanje u programu.  Asinkrono ponašanje prava je korist sheme funkcije povratnog poziva. U shemi asinkronog povratnog poziva, rezultat glavne funkcije treba dobiti za program prije nego što se dobije rezultat funkcije povratnog poziva. To je moguće učiniti na C ++; međutim, C ++ ima knjižnicu koja se naziva budućnost kako bi se zajamčilo ponašanje sheme asinkronog povratnog poziva.

Ovaj članak objašnjava osnovnu shemu funkcija povratnog poziva. Dosta je toga s čistim C++. Što se tiče povratnog poziva, također je objašnjeno osnovno ponašanje buduće knjižnice. Za razumijevanje ovog članka potrebno je osnovno znanje o C ++-u i njegovim uputama.

Sadržaj članka

Osnovna shema funkcije povratnog poziva

Shema funkcije povratnog poziva treba glavnu funkciju i samu funkciju povratnog poziva. Deklaracija funkcije povratnog poziva dio je popisa parametara glavne funkcije. Definicija funkcije povratnog poziva naznačena je u pozivu funkcije glavne funkcije. Funkcija povratnog poziva zapravo se poziva unutar definicije glavne funkcije. Sljedeći program to ilustrira:

#include
pomoću prostora imena std;
int principalFn (char ch [], int (* ptr) (int))

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

int cb (int iden)

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

int main ()

int (* ptr) (int) = &cb;
char cha [] = "i";
glavniFn (cha, cb);
return 0;

Izlaz je:

funkcija povratnog poziva
glavna funkcija: 1 i 2

Glavnu funkciju identificira glavniFn (). Funkcija povratnog poziva identificirana je cb (). Funkcija povratnog poziva definirana je izvan glavne funkcije, ali zapravo se poziva unutar glavne funkcije.

Zabilježite izjavu funkcije povratnog poziva kao parametar na popisu parametara glavne izjave funkcije. Izjava funkcije povratnog poziva je "int (* ptr) (int)". Zabilježite izraz funkcije povratnog poziva, poput poziva funkcije, u definiciji glavne funkcije; tamo se prosljeđuje bilo koji argument za poziv funkcije povratnog poziva. Izjava za ovaj poziv funkcije je:

int idr = (* ptr) (id2);

Gdje je id2 argument. ptr je dio parametra, pokazivač, koji će biti povezan s referencom funkcije povratnog poziva u funkciji main ().

Obratite pažnju na izraz:

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

U funkciji main () koja povezuje deklaraciju (bez definicije) funkcije povratnog poziva s imenom definicije iste funkcije povratnog poziva.

Glavna funkcija se u funkciji main () naziva:

glavniFn (cha, cb);

Gdje je cha niz, a cb je ime funkcije povratnog poziva bez ijednog argumenta.

Sinkrono ponašanje funkcije povratnog poziva

Razmotrite sljedeći program:

#include
pomoću prostora imena std;
void principalFn (void (* ptr) ())

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

praznina cb ()

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

void fn ()

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

int main ()

void (* ptr) () = &cb;
glavnicaFn (cb);
fn ();
return 0;

Izlaz je:

glavna funkcija
funkcija povratnog poziva
vidio

Ovdje je nova funkcija. Sve što nova funkcija radi, jest prikaz izlaza, "viđeno". U funkciji main () poziva se glavna funkcija, a zatim se poziva nova funkcija, fn (). Izlaz pokazuje da je izvršen kôd za glavnu funkciju, zatim onaj za funkciju povratnog poziva i na kraju da je izvršen za funkciju fn (). To je sinkrono (jednonitno) ponašanje.

Ako se radi o asinkronom ponašanju, kada se redom pozivaju tri segmenta koda, može se izvršiti prvi segment koda, nakon čega slijedi izvršavanje trećeg segmenta koda, prije nego što se izvrši drugi segment koda.

Pa, funkcija fn () može se pozvati iz definicije glavne funkcije, umjesto iz glavne () funkcije, kako slijedi:

#include
pomoću prostora imena std;
void fn ()

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

void principalFn (void (* ptr) ())

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

praznina cb ()

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

int main ()

void (* ptr) () = &cb;
glavnicaFn (cb);
return 0;

Izlaz je:

glavna funkcija
vidio
funkcija povratnog poziva

Ovo je imitacija asinkronog ponašanja. To nije asinkrono ponašanje. To je još uvijek sinkrono ponašanje.

Također, redoslijed izvršavanja segmenta koda glavne funkcije i segmenta koda funkcije povratnog poziva mogu se zamijeniti u definiciji glavne funkcije. Sljedeći program to ilustrira:

#include
pomoću prostora imena std;
 
void principalFn (void (* ptr) ())

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

praznina cb ()

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

void fn ()

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

int main ()

void (* ptr) () = &cb;
glavnicaFn (cb);
fn ();
return 0;

Izlaz je sada,

funkcija povratnog poziva
glavna funkcija
vidio

Ovo je također imitacija asinkronog ponašanja. To nije asinkrono ponašanje. To je još uvijek sinkrono ponašanje. Istinsko asinkrono ponašanje može se dobiti kako je objašnjeno u sljedećem odjeljku ili u knjižnici u budućnosti.

Asinkrono ponašanje s funkcijom povratnog poziva

Pseudo-kôd za osnovnu shemu asinkronih funkcija povratnog poziva je:

tip izlaza;
tip cb (izlaz tipa)

// izjave

tip principalFn (tip ulaza, tip cb (izlaz tipa))

// izjave

Zabilježite položaj ulaznih i izlaznih podataka na različitim mjestima pseudo-koda. Ulaz funkcije povratnog poziva je njegov izlaz. Parametri glavne funkcije su ulazni parametar za opći kod i parametar za funkciju povratnog poziva. Pomoću ove sheme može se izvršiti (pozvati) treća funkcija u funkciji main () prije čitanja izlaza funkcije povratnog poziva (još uvijek u funkciji main ()). Sljedeći kod to ilustrira:

#include
pomoću prostora imena std;
char * izlaz;
praznina cb (iscrtavanje [])

izlaz = izlaz;

void principalFn (char input [], void (* ptr) (char [50]))

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

void fn ()

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

int main ()

char input [] = "funkcija povratnog poziva";
void (* ptr) (char []) = &cb;
glavniFn (ulaz, cb);
fn ();
cout<return 0;

Izlaz programa je:

glavna funkcija
vidio
funkcija povratnog poziva

U ovom određenom kodu izlazni i ulazni datum su isti datum. Rezultat trećeg poziva funkcije u funkciji main () prikazan je prije rezultata funkcije povratnog poziva. Funkcija povratnog poziva izvršena je, dovršila i dodijelila svoj rezultat (vrijednost) varijabli, izlaz, omogućujući programu da nastavi bez njezinih smetnji. U glavnoj () funkciji koristio se (čitao i prikazivao) izlaz funkcije povratnog poziva kada je to trebalo, što je dovelo do asinkronog ponašanja za cijelu shemu.

Ovo je jednonitni način za postizanje asinkronog ponašanja funkcije povratnog poziva s čistim C++.

Osnovno korištenje buduće knjižnice

Ideja sheme asinkronog povratnog poziva je da se glavna funkcija vrati prije nego što se funkcija povratnog poziva vrati. To je učinjeno neizravno, učinkovito, u gore navedenom kodu.

Primijetite iz gornjeg koda da funkcija povratnog poziva prima glavni ulaz za kôd i daje glavni izlaz za kôd. Knjižnica C ++, budući, ima funkciju koja se naziva sync (). Prvi argument ove funkcije je referenca funkcije povratnog poziva; drugi argument je ulaz u funkciju povratnog poziva. Funkcija sync () vraća se bez čekanja da se izvrši funkcija povratnog poziva, ali omogućuje dovršavanje funkcije povratnog poziva. To osigurava asinkrono ponašanje. Dok se funkcija povratnog poziva nastavlja izvršavati, budući da se funkcija sync () već vratila, izrazi ispod nje nastavljaju se izvršavati. To je poput idealnog asinkronog ponašanja.

Gornji program je prepisan u nastavku, uzimajući u obzir buduću knjižnicu i njezinu funkciju sync ():

#include
#include
#include
pomoću prostora imena std;
budućnost izlaz;
niz cb (niz stri)

povratak stri;

void principalFn (unos niza)

izlaz = asinkronizacija (cb, ulaz);
cout<<"principal function"<<'\n';

void fn ()

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

int main ()

string input = string ("funkcija povratnog poziva");
glavniFn (ulaz);
fn ();
niz ret = izlaz.dobiti(); // čeka povratak poziva ako je potrebno
cout<return 0;

Funkcija sync () konačno pohranjuje izlaz funkcije povratnog poziva u budući objekt. Očekivani izlaz može se dobiti u funkciji main (), koristeći funkciju člana get () budućeg objekta.

Zaključak

Funkcija povratnog poziva je funkcija koja je argument, a ne parametar druge funkcije. Shema funkcije povratnog poziva treba glavnu funkciju i samu funkciju povratnog poziva. Deklaracija funkcije povratnog poziva dio je popisa parametara glavne funkcije. Definicija funkcije povratnog poziva naznačena je u pozivu funkcije glavne funkcije (u main ()). Funkcija povratnog poziva zapravo se poziva unutar definicije glavne funkcije.

Shema funkcije povratnog poziva nije nužno asinkrona. Da biste bili sigurni da je shema funkcije povratnog poziva asinkrona, unesite glavni ulaz u kod, ulaz u funkciju povratnog poziva; napraviti glavni izlaz koda, izlaz funkcije povratnog poziva; pohraniti izlaz funkcije povratnog poziva u varijablu ili strukturu podataka. U funkciji main (), nakon poziva glavne funkcije, izvršite ostale izraze aplikacije. Kada je potreban izlaz funkcije povratnog poziva, u glavnoj () funkciji upotrijebite (pročitajte i prikažite) tu i tamo.

Najbolji emulatori igraće konzole za Linux
Ovaj će članak navesti popularni softver za emulaciju igraće konzole dostupan za Linux. Emulacija je sloj kompatibilnosti softvera koji oponaša hardve...
Najbolji Linux Distros za igre na sreću 2021. godine
Linux operativni sustav daleko je prevalio svoj izvorni, jednostavni izgled zasnovan na poslužitelju. Ovaj se OS posljednjih godina izuzetno poboljšao...
Kako snimiti i struji svoju igraću sesiju na Linuxu
U prošlosti se igranje igara smatralo samo hobijem, ali s vremenom je igračka industrija zabilježila ogroman rast u pogledu tehnologije i broja igrača...