En tilbagekaldsfunktion er en funktion, som er et argument, ikke en parameter, i en anden funktion. Den anden funktion kan kaldes hovedfunktionen. Så to funktioner er involveret: hovedfunktionen og selve tilbagekaldsfunktionen. I parameterlisten for hovedfunktionen er erklæringen om tilbagekaldsfunktionen uden dens definition til stede, ligesom objektdeklarationer uden tildeling er til stede. Hovedfunktionen kaldes med argumenter (i main ()). Et af argumenterne i hovedfunktionsopkaldet er den effektive definition af tilbagekaldsfunktionen. I C ++ er dette argument en reference til definitionen af tilbagekaldsfunktionen; det er ikke den egentlige definition. Selve tilbagekaldsfunktionen kaldes faktisk inden for definitionen af hovedfunktionen.
Den grundlæggende tilbagekaldsfunktion i C ++ garanterer ikke asynkron adfærd i et program. Asynkron adfærd er den reelle fordel ved tilbagekaldelsesfunktionsordningen. I det asynkrone tilbagekaldsfunktionsskema skal resultatet af hovedfunktionen indhentes for programmet, før resultatet af tilbagekaldsfunktionen opnås. Det er muligt at gøre dette i C ++; C ++ har imidlertid et bibliotek kaldet fremtid for at garantere opførslen af det asynkrone tilbagekaldsfunktionsskema.
Denne artikel forklarer det grundlæggende callback -funktionsskema. Meget af det er med ren C ++. Hvad tilbagekaldelsen angår, forklares også det fremtidige biblioteks grundlæggende adfærd. Grundlæggende viden om C ++ og dets tips er nødvendig for forståelsen af denne artikel.
Artikelindhold
- Grundlæggende tilbagekaldsfunktionsskema
- Synkron adfærd med tilbagekaldsfunktion
- Asynkron adfærd med tilbagekaldsfunktion
- Grundlæggende brug af det fremtidige bibliotek
- Konklusion
Grundlæggende tilbagekaldsfunktionsskema
Et opkaldsfunktionsskema har brug for en hovedfunktion og selve tilbagekaldsfunktionen. Erklæringen om tilbagekaldsfunktionen er en del af parameterlisten for hovedfunktionen. Definitionen af tilbagekaldsfunktionen er angivet i funktionsopkaldet til hovedfunktionen. Tilbagekaldsfunktionen kaldes faktisk inden for definitionen af hovedfunktionen. Følgende program illustrerer dette:
#omfatte
ved brug af navnerumtimer;
intmainFn(forkælelsekap[],int (*ptr)(int))
{
intid1= 1;
intid2= 2;
intsom regel= (*ptr)(id2);
koste<<'hovedfunktion:'<<id1<<''<<kap<<''<<som regel<<' n';
Vend tilbageid1;
}
intcb(intiden)
{
koste<<'tilbagekaldsfunktion'<<' n';
Vend tilbageiden;
}
intvigtigste()
{
int (*ptr)(int) = &cb;
forkælelseingen[] = 'og';
mainFn(far, cb);
Vend tilbage 0;
}
Outputtet er:
tilbagekaldsfunktion
hovedfunktion: 1 og 2
Hovedfunktionen identificeres af principalFn (). Tilbagekaldsfunktionen identificeres med cb (). Tilbagekaldelsesfunktionen defineres uden for hovedfunktionen, men kaldes faktisk inden for hovedfunktionen.
Bemærk erklæringen om tilbagekaldsfunktionen som en parameter i parameterlisten for hovedfunktionserklæringen. Erklæringen om tilbagekaldsfunktionen er int (*ptr) (int). Bemærk tilbagekaldelsesfunktionsudtrykket, ligesom et funktionsopkald, i definitionen af hovedfunktionen; ethvert argument for opkald til funktionsopkald sendes der. Erklæringen for dette funktionsopkald er:
intsom regel= (*ptr)(id2);
Hvor id2 er et argument. ptr er en del af parameteren, en markør, der vil blive knyttet til referencen til tilbagekaldsfunktionen i hovedfunktionen ().
Bemærk udtrykket:
int (*ptr)(int) = &cb;I hovedfunktionen (), der forbinder erklæringen (uden definition) af tilbagekaldsfunktionen til navnet på definitionen af den samme tilbagekaldsfunktion.
Hovedfunktionen kaldes i hovedfunktionen () som:
mainFn(far, cb);Hvor cha er en streng og cb er navnet på tilbagekaldsfunktionen uden nogen af dens argumenter.
Synkron opførsel af tilbagekaldsfunktion
Overvej følgende program:
#omfatteved brug af navnerumtimer;
ugyldigmainFn(ugyldig (*ptr)())
{
koste<<'hovedfunktion'<<' n';
(*ptr)();
}
ugyldigcb()
{
koste<<'tilbagekaldsfunktion'<<' n';
}
ugyldigfn()
{
koste<<'set'<<' n';
}
intvigtigste()
{
ugyldig (*ptr)() = &cb;
mainFn(cb);
fn();
Vend tilbage 0;
}
Outputtet er:
hovedfunktiontilbagekaldsfunktion
set
Der er en ny funktion her. Alt den nye funktion gør, er at vise output, set. I hovedfunktionen () kaldes hovedfunktionen, derefter kaldes den nye funktion, fn (). Outputtet viser, at koden for hovedfunktionen blev udført, derefter blev funktionen for tilbagekaldsfunktionen udført, og endelig blev funktionen for fn () udført. Dette er synkron (enkeltrådet) adfærd.
Hvis det var asynkron adfærd, når tre kodesegmenter kaldes i rækkefølge, kan det første kodesegment eksekveres, i stedet efterfulgt af udførelsen af det tredje kodesegment, før det andet kodesegment udføres.
Nå, funktionen, fn () kan kaldes inde fra definitionen af hovedfunktionen i stedet for inden for hovedfunktionen () som følger:
#omfatteved brug af navnerumtimer;
ugyldigfn()
{
koste<<'set'<<' n';
}
ugyldigmainFn(ugyldig (*ptr)())
{
koste<<'hovedfunktion'<<' n';
fn();
(*ptr)();
}
ugyldigcb()
{
koste<<'tilbagekaldsfunktion'<<' n';
}
intvigtigste()
{
ugyldig (*ptr)() = &cb;
mainFn(cb);
Vend tilbage 0;
}
Outputtet er:
hovedfunktionset
tilbagekaldsfunktion
Dette er en efterligning af asynkron adfærd. Det er ikke asynkron adfærd. Det er stadig synkron adfærd.
Også rækkefølgen af udførelsen af kodesegmentet for hovedfunktionen og kodesegmentet for tilbagekaldsfunktionen kan byttes i definitionen af hovedfunktionen. Følgende program illustrerer dette:
#omfatteved brug af navnerumtimer;
ugyldigmainFn(ugyldig (*ptr)())
{
(*ptr)();
koste<<'hovedfunktion'<<' n';
}
ugyldigcb()
{
koste<<'tilbagekaldsfunktion'<<' n';
}
ugyldigfn()
{
koste<<'set'<<' n';
}
intvigtigste()
{
ugyldig (*ptr)() = &cb;
mainFn(cb);
fn();
Vend tilbage 0;
}
Output er nu,
tilbagekaldsfunktionhovedfunktion
set
Dette er også en efterligning af asynkron adfærd. Det er ikke asynkron adfærd. Det er stadig synkron adfærd. Ægte asynkron adfærd kan opnås som forklaret i det næste afsnit eller med biblioteket, fremtid.
Asynkron adfærd med tilbagekaldsfunktion
Pseudokoden for det grundlæggende asynkrone tilbagekaldsfunktionsskema er:
type output;type cb(type output)
{
// udsagn
}
type principalFn(type input, type cb(type output))
{
// udsagn
}
Bemærk positionerne for input- og outputdataene på de forskellige steder i pseudokoden. Tilbagekaldsfunktionens input er dens output. Parametrene for hovedfunktionen er inputparameteren for den generelle kode og parameteren for tilbagekaldsfunktionen. Med dette skema kan en tredje funktion udføres (kaldes) i hovedfunktionen (), før output fra tilbagekaldsfunktionen læses (stadig i hovedfunktionen ()). Følgende kode illustrerer dette:
#omfatteved brug af navnerumtimer;
forkælelse *produktion;
ugyldigcb(forkælelseud[])
{
produktion=ud;
}
ugyldigmainFn(forkælelseinput[],ugyldig (*ptr)(forkælelse[halvtreds]))
{
(*ptr)(input);
koste<<'hovedfunktion'<<' n';
}
ugyldigfn()
{
koste<<'set'<<' n';
}
intvigtigste()
{
forkælelseinput[] = 'tilbagekaldsfunktion';
ugyldig (*ptr)(forkælelse[]) = &cb;
mainFn(input, cb);
fn();
koste<<produktion<<' n';
Vend tilbage 0;
}
Programoutput er:
hovedfunktionset
tilbagekaldsfunktion
I denne særlige kode er output- og inputdatoen tilfældigvis det samme nulpunkt. Resultatet af det tredje funktionsopkald i hovedfunktionen () er blevet vist før resultatet af tilbagekaldsfunktionen. Tilbagekaldsfunktionen udført, afsluttet og tildelt sit resultat (værdi) til variablen, output, så programmet kunne fortsætte uden interferens. I hovedfunktionen () blev output fra tilbagekaldsfunktionen brugt (læst og vist), når det var nødvendigt, hvilket førte til asynkron adfærd for hele ordningen.
Dette er den enkeltrådede måde at opnå tilbagekaldsfunktion asynkron adfærd med ren C ++.
Grundlæggende brug af det fremtidige bibliotek
Ideen med det asynkrone tilbagekaldsfunktionsskema er, at hovedfunktionen vender tilbage, før tilbagekaldsfunktionen vender tilbage. Dette blev gjort indirekte, effektivt i ovenstående kode.
Bemærk fra ovenstående kode, at tilbagekaldsfunktionen modtager hovedindgangen til koden og producerer hovedoutput for koden. C ++ - biblioteket, future, har en funktion kaldet sync (). Det første argument til denne funktion er referencefunktionsreferencen; det andet argument er input til tilbagekaldsfunktionen. Synkroniseringsfunktionen () vender tilbage uden at vente på, at tilbagekaldsfunktionen udføres, men tillader genopkaldsfunktionen. Dette giver asynkron adfærd. Mens tilbagekaldsfunktionen fortsætter med at blive udført, da synkroniseringsfunktionen () allerede er vendt tilbage, fortsætter udsagnene herunder. Dette er som ideel asynkron adfærd.
Ovenstående program er blevet omskrevet herunder under hensyntagen til det fremtidige bibliotek og dets synkroniseringsfunktion ():
#omfatte#omfatte
#omfatte
ved brug af navnerumtimer;
fremtid<snor>produktion;
streng cb(streng stri)
{
Vend tilbagestri;
}
ugyldigmainFn(streng input)
{
produktion=asynk(cb, input);
koste<<'hovedfunktion'<<' n';
}
ugyldigfn()
{
koste<<'set'<<' n';
}
intvigtigste()
{
streng input=snor('tilbagekaldsfunktion');
mainFn(input);
fn();
string ret=produktion.få(); // venter på tilbagekald for at vende tilbage om nødvendigt
koste<<ret<<' n';
Vend tilbage 0;
}
Sync () -funktionen gemmer endelig output fra tilbagekaldsfunktionen i det fremtidige objekt. Det forventede output kan opnås i hovedfunktionen () ved hjælp af get () - medlemsfunktionen for det fremtidige objekt.
Konklusion
En tilbagekaldsfunktion er en funktion, som er et argument, ikke en parameter, i en anden funktion. Et opkaldsfunktionsskema har brug for en hovedfunktion og selve tilbagekaldsfunktionen. Erklæringen om tilbagekaldsfunktionen er en del af parameterlisten for hovedfunktionen. Definitionen af tilbagekaldsfunktionen er angivet i funktionsopkaldet til hovedfunktionen (i main ()). Tilbagekaldsfunktionen kaldes faktisk inden for definitionen af hovedfunktionen.
Et tilbagekaldsfunktionsskema er ikke nødvendigvis asynkron. For at være sikker på, at tilbagekaldsfunktionsskemaet er asynkron, skal du indtaste hovedindgangen til koden, input til tilbagekaldsfunktionen; lav hovedoutput af koden, output fra tilbagekaldsfunktionen; gemme output fra tilbagekaldsfunktionen i en variabel eller datastruktur. I hovedfunktionen (), efter at have kaldt til hovedfunktionen, skal du udføre andre udsagn i applikationen. Når output fra tilbagekaldsfunktionen er nødvendig, skal du (læse og vise) det i hovedfunktionen (), der og derefter.