Funkcija povratnog poziva u C ++

Callback Function C

Povratni poziv funkcija je funkcija koja je argument, a ne parametar u drugoj funkciji. Druga funkcija se može nazvati glavnom funkcijom. Dakle, uključene su dvije funkcije: glavna funkcija i sama funkcija povratnog poziva. U popisu parametara glavne funkcije prisutna je deklaracija funkcije povratnog poziva bez njezine definicije, baš kao što su prisutne deklaracije objekata bez dodjeljivanja. Glavna funkcija poziva se s argumentima (u main ()). Jedan od argumenata u pozivu glavne funkcije je učinkovita definicija funkcije povratnog poziva. U C ++, ovaj argument je 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 ++ ne jamči asinhrono ponašanje u programu. Asinkrono ponašanje prava je korist od sheme funkcija povratnog poziva. U shemi asinkronih funkcija povratnog poziva rezultat glavne funkcije treba dobiti za program prije nego što se dobije rezultat funkcije povratnog poziva. To je moguće učiniti u C ++; međutim, C ++ ima knjižnicu koja se zove future kako bi zajamčila ponašanje asinkrone sheme funkcija povratnog poziva.



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



Sadržaj članka

Osnovna shema funkcija 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 navedena je u pozivu funkcije glavne funkcije. Funkcija povratnog poziva zapravo se poziva unutar definicije glavne funkcije. Sljedeći program to ilustrira:



#uključi

koristeći imenski prostorsati;



intmainFn(charCH[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

intobično= (*ptr)(id2);

trošak<<'glavna funkcija:'<<id1<<''<<CH<<''<<obično<<' n';

povratakid1;

}


intcb(intiden)

{

trošak<<'funkcija povratnog poziva'<<' n';

povratakiden;

}


intglavni()

{

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

charNe[] = 'i';

mainFn(otac, cb);



povratak 0;

}

Izlaz je:

funkcija povratnog poziva

glavna funkcija: 1 i 2

Glavna funkcija identificirana je principalomFn (). Funkcija povratnog poziva identificirana je cb (). Funkcija povratnog poziva definirana je izvan glavne funkcije, ali se zapravo poziva unutar glavne funkcije.

Obratite pozornost na deklaraciju funkcije povratnog poziva kao parametra u popisu parametara deklaracije glavne funkcije. Deklaracija funkcije povratnog poziva je int (*ptr) (int). Obratite pažnju na izraz funkcije povratnog poziva, poput poziva funkcije, u definiciji glavne funkcije; tamo se prosljeđuje svaki argument za poziv funkcije povratnog poziva. Izraz za ovaj poziv funkcije je:



intobično= (*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:

mainFn(otac, cb);

Gdje je cha niz, a cb naziv funkcije povratnog poziva bez ikakvog argumenta.

Sinkrono ponašanje funkcije povratnog poziva

Razmotrite sljedeći program:

#uključi

koristeći imenski prostorsati;



poništitimainFn(poništiti (*ptr)())

{

trošak<<'glavna funkcija'<<' n';

(*ptr)();

}


poništiticb()

{

trošak<<'funkcija povratnog poziva'<<' n';

}


poništitifn()

{

trošak<<'vidio'<<' n';

}


intglavni()

{

poništiti (*ptr)() = &cb;

mainFn(cb);

fn();



povratak 0;

}

Izlaz je:

glavna funkcija

funkcija povratnog poziva

vidio

Ovdje je nova funkcija. Sve što nova funkcija radi je prikazati izlaz. U funkciji main () poziva se glavna funkcija, zatim nova funkcija, fn (). Izlaz pokazuje da je izvršen kôd za glavnu funkciju, zatim za funkciju povratnog poziva i na kraju za funkciju fn (). To je sinkrono (jednonavojno) ponašanje.

Da se radi o asinkronom ponašanju, kada se pozovu tri segmenta koda, može se izvršiti prvi segment koda, nakon čega slijedi izvršenje trećeg segmenta koda, prije nego što se izvede drugi segment koda.

Pa, funkcija, fn () se može pozvati unutar definicije glavne funkcije, umjesto iz funkcije main (), na sljedeći način:

#uključi

koristeći imenski prostorsati;



poništitifn()

{

trošak<<'vidio'<<' n';

}


poništitimainFn(poništiti (*ptr)())

{

trošak<<'glavna funkcija'<<' n';

fn();

(*ptr)();

}


poništiticb()

{

trošak<<'funkcija povratnog poziva'<<' n';

}


intglavni()

{

poništiti (*ptr)() = &cb;

mainFn(cb);



povratak 0;

}

Izlaz je:

glavna funkcija

vidio

funkcija povratnog poziva

Ovo je imitacija asinhronog ponašanja. To nije asinhrono ponašanje. To je još uvijek sinkrono ponašanje.

Također, redoslijed izvođenja kodnog segmenta glavne funkcije i segmentnog koda funkcije povratnog poziva mogu se zamijeniti u definiciji glavne funkcije. Sljedeći program to ilustrira:

#uključi

koristeći imenski prostorsati;



poništitimainFn(poništiti (*ptr)())

{

(*ptr)();

trošak<<'glavna funkcija'<<' n';

}


poništiticb()

{

trošak<<'funkcija povratnog poziva'<<' n';

}


poništitifn()

{

trošak<<'vidio'<<' n';

}


intglavni()

{

poništiti (*ptr)() = &cb;

mainFn(cb);

fn();



povratak 0;

}

Izlaz je sada,

funkcija povratnog poziva

glavna funkcija

vidio

Ovo je također imitacija asinhronog ponašanja. To nije asinhrono ponašanje. To je još uvijek sinkrono ponašanje. Istinsko asinhrono ponašanje može se postići kako je objašnjeno u sljedećem odjeljku ili s knjižnicom, budućnost.

Asinkrono ponašanje s funkcijom povratnog poziva

Pseudokod za osnovnu shemu funkcija asinkronog povratnog poziva je:

tip izlaza;

tip cb(tip izlaza)

{

// izjave

}


vrsta principalFn(tip ulaz, tip cb(tip izlaza))

{

// izjave

}

Zabilježite položaje ulaznih i izlaznih podataka na različitim mjestima pseudo koda. Ulaz funkcije povratnog poziva je njezin 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:

#uključi

koristeći imenski prostorsati;

char *izlaz;


poništiticb(charvan[])

{

izlaz=van;

}



poništitimainFn(charulazni[],poništiti (*ptr)(char[pedeset]))

{

(*ptr)(ulazni);

trošak<<'glavna funkcija'<<' n';

}


poništitifn()

{

trošak<<'vidio'<<' n';

}


intglavni()

{

charulazni[] = 'funkcija povratnog poziva';

poništiti (*ptr)(char[]) = &cb;

mainFn(ulaz, cb);

fn();

trošak<<izlaz<<' n';



povratak 0;

}

Izlaz programa je:

glavna funkcija

vidio

funkcija povratnog poziva

U ovom posebnom kodu izlazni i ulazni datum su isti podatak. Rezultat poziva treće funkcije u funkciji main () prikazan je prije rezultata funkcije povratnog poziva. Funkcija povratnog poziva izvršila se, završila i dodijelila svoj rezultat (vrijednost) varijabli, izlaz, dopuštajući programu da nastavi bez smetnji. U funkciji main () izlaz funkcije povratnog poziva korišten je (čita se i prikazuje) kada je to bilo potrebno, što je dovelo do asinkronog ponašanja za cijelu shemu.

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

Osnovno korištenje buduće Knjižnice

Ideja sheme funkcija 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 gornjem kodu.

Primijetite iz gornjeg koda da funkcija povratnog poziva prima glavni ulaz za kôd i proizvodi glavni izlaz za kôd. C ++ knjižnica, budući, ima funkciju koja se zove 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 dopušta 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, naredbe ispod nje nastavljaju se izvršavati. Ovo je poput idealnog asinhronog ponašanja.

Gore navedeni program je dolje prepisan, uzimajući u obzir buduću biblioteku i njenu funkciju sync ():

#uključi

#uključi

#uključi

koristeći imenski prostorsati;

budućnost<niz>izlaz;

niz cb(žica stri)

{

povratakstri;

}



poništitimainFn(unos niza)

{

izlaz=asink(cb, ulaz);

trošak<<'glavna funkcija'<<' n';

}


poništitifn()

{

trošak<<'vidio'<<' n';

}


intglavni()

{

unos niza=niz('funkcija povratnog poziva');

mainFn(ulazni);

fn();

string ret=izlaz.dobiti(); // čeka da se povratni poziv vrati ako je potrebno

trošak<<pravo<<' n';



povratak 0;

}

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

Zaključak

Povratni poziv funkcija je funkcija koja je argument, a ne parametar u drugoj funkciji. 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 navedena 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, izvršite glavni ulaz u kôd, 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 pozivanja funkcije principal, izvršite druge izraze aplikacije. Kad je potreban izlaz funkcije povratnog poziva, u funkciji main () upotrijebite je (pročitajte i prikažite) tu i tamo.