Tilbakeringingsfunksjon i C ++

Callback Function C



En tilbakeringingsfunksjon er en funksjon, som er et argument, ikke en parameter, i en annen funksjon. Den andre funksjonen kan kalles hovedfunksjonen. Så to funksjoner er involvert: hovedfunksjonen og selve tilbakeringingsfunksjonen. I parameterlisten til hovedfunksjonen er erklæringen om tilbakeringingsfunksjonen uten dens definisjon til stede, akkurat som objektdeklarasjoner uten tildeling er tilstede. Hovedfunksjonen kalles med argumenter (i main ()). Et av argumentene i hovedfunksjonsanropet er den effektive definisjonen av tilbakeringingsfunksjonen. I C ++ er dette argumentet en referanse til definisjonen av tilbakeringingsfunksjonen; det er ikke den faktiske definisjonen. Selve tilbakeringingsfunksjonen kalles faktisk innenfor definisjonen av hovedfunksjonen.

Den grunnleggende tilbakeringingsfunksjonen i C ++ garanterer ikke asynkron oppførsel i et program. Asynkron oppførsel er den virkelige fordelen med tilbakeringingsfunksjonsordningen. I det asynkrone tilbakeringingsfunksjonsskjemaet, bør resultatet av hovedfunksjonen hentes for programmet før resultatet av tilbakeringingsfunksjonen oppnås. Det er mulig å gjøre dette i C ++; C ++ har imidlertid et bibliotek som heter fremtiden for å garantere oppførselen til det asynkrone tilbakekallingsfunksjonsskjemaet.







Denne artikkelen forklarer det grunnleggende tilbakeringingsfunksjonsskjemaet. Mye av det er med ren C ++. Når det gjelder tilbakeringing, forklares også den grunnleggende oppførselen til det fremtidige biblioteket. Grunnleggende kunnskap om C ++ og dets tips er nødvendig for å forstå denne artikkelen.



Artikkelinnhold

Grunnleggende tilbakeringingsfunksjon

Et tilbakeringingsfunksjonsskjema trenger en hovedfunksjon, og selve tilbakeringingsfunksjonen. Erklæringen om tilbakeringingsfunksjonen er en del av parameterlisten til hovedfunksjonen. Definisjonen av tilbakeringingsfunksjonen er angitt i funksjonsanropet til hovedfunksjonen. Tilbakekallingsfunksjonen kalles faktisk innenfor definisjonen av hovedfunksjonen. Følgende program illustrerer dette:



#inkludere

ved hjelp av navneområdetimer;



intmainFn(røyekap[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

intvanligvis= (*ptr)(id2);

koste<<'hovedfunksjon:'<<id1<<''<<kap<<''<<vanligvis<<' n';

komme tilbakeid1;

}


intcb(intiden)

{

koste<<'tilbakeringingsfunksjon'<<' n';

komme tilbakeiden;

}


inthoved-()

{

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

røyeNei[] = 'og';

mainFn(far, cb);



komme tilbake 0;

}

Utgangen er:





tilbakeringingsfunksjon

hovedfunksjon: 1 og 2

Hovedfunksjonen identifiseres av principalFn (). Tilbakekallingsfunksjonen identifiseres med cb (). Tilbakekallingsfunksjonen er definert utenfor hovedfunksjonen, men faktisk kalt innen hovedfunksjonen.

Legg merke til erklæringen om tilbakeringingsfunksjonen som en parameter i parameterlisten til hovedfunksjonserklæringen. Erklæringen om tilbakeringingsfunksjonen er int (*ptr) (int). Legg merke til tilbakeringingsfunksjonsuttrykket, som et funksjonsanrop, i definisjonen av hovedfunksjonen; ethvert argument for tilbakeringingsfunksjonsanropet sendes der. Erklæringen for denne funksjonskallingen er:



intvanligvis= (*ptr)(id2);

Hvor id2 er et argument. ptr er en del av parameteren, en peker, som vil bli knyttet til referansen til tilbakeringingsfunksjonen i hovedfunksjonen ().

Legg merke til uttrykket:

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

I hovedfunksjonen (), som knytter erklæringen (uten definisjon) for tilbakeringingsfunksjonen til navnet på definisjonen av den samme tilbakeringingsfunksjonen.

Hovedfunksjonen kalles i hovedfunksjonen () som:

mainFn(far, cb);

Hvor cha er en streng og cb er navnet på tilbakeringingsfunksjonen uten noen av argumentene.

Synkron oppførsel av tilbakeringingsfunksjon

Vurder følgende program:

#inkludere

ved hjelp av navneområdetimer;



tomrommainFn(tomrom (*ptr)())

{

koste<<'hovedfunksjon'<<' n';

(*ptr)();

}


tomromcb()

{

koste<<'tilbakeringingsfunksjon'<<' n';

}


tomromfn()

{

koste<<'sett'<<' n';

}


inthoved-()

{

tomrom (*ptr)() = &cb;

mainFn(cb);

fn();



komme tilbake 0;

}

Utgangen er:

hovedfunksjon

tilbakeringingsfunksjon

sett

Det er en ny funksjon her. Alt den nye funksjonen gjør, er å vise utgangen, sett. I hovedfunksjonen () kalles hovedfunksjonen, deretter kalles den nye funksjonen, fn (). Utgangen viser at koden for hovedfunksjonen ble utført, deretter ble den for tilbakeringingsfunksjonen utført, og til slutt ble den for fn () -funksjonen utført. Dette er synkron (enkelttrådet) oppførsel.

Hvis det var asynkron oppførsel, når tre kodesegmenter kalles i rekkefølge, kan det første kodesegmentet utføres, etterfulgt av utførelsen av det tredje kodesegmentet, før det andre kodesegmentet utføres.

Vel, funksjonen, fn () kan kalles fra definisjonen av hovedfunksjonen, i stedet for fra hovedfunksjonen (), som følger:

#inkludere

ved hjelp av navneområdetimer;



tomromfn()

{

koste<<'sett'<<' n';

}


tomrommainFn(tomrom (*ptr)())

{

koste<<'hovedfunksjon'<<' n';

fn();

(*ptr)();

}


tomromcb()

{

koste<<'tilbakeringingsfunksjon'<<' n';

}


inthoved-()

{

tomrom (*ptr)() = &cb;

mainFn(cb);



komme tilbake 0;

}

Utgangen er:

hovedfunksjon

sett

tilbakeringingsfunksjon

Dette er en etterligning av asynkron oppførsel. Det er ikke asynkron oppførsel. Det er fortsatt synkron oppførsel.

Også rekkefølgen for utførelse av kodesegmentet til hovedfunksjonen og kodesegmentet til tilbakeringingsfunksjonen kan byttes i definisjonen av hovedfunksjonen. Følgende program illustrerer dette:

#inkludere

ved hjelp av navneområdetimer;



tomrommainFn(tomrom (*ptr)())

{

(*ptr)();

koste<<'hovedfunksjon'<<' n';

}


tomromcb()

{

koste<<'tilbakeringingsfunksjon'<<' n';

}


tomromfn()

{

koste<<'sett'<<' n';

}


inthoved-()

{

tomrom (*ptr)() = &cb;

mainFn(cb);

fn();



komme tilbake 0;

}

Utgangen er nå,

tilbakeringingsfunksjon

hovedfunksjon

sett

Dette er også en etterligning av asynkron oppførsel. Det er ikke asynkron oppførsel. Det er fortsatt synkron oppførsel. Ekte asynkron oppførsel kan oppnås som forklart i neste avsnitt eller med biblioteket, fremtid.

Asynkron oppførsel med tilbakeringingsfunksjon

Pseudokoden for det grunnleggende asynkrone tilbakeringingsfunksjonsskjemaet er:

type utgang;

type cb(type utgang)

{

// utsagn

}


type principalFn(type input, type cb(type utgang))

{

// utsagn

}

Legg merke til posisjonene til inngangs- og utdataene på de forskjellige stedene i pseudokoden. Inngangen til tilbakeringingsfunksjonen er dens utgang. Parametrene til hovedfunksjonen er inngangsparameteren for den generelle koden og parameteren for tilbakeringingsfunksjonen. Med denne ordningen kan en tredje funksjon utføres (kalles) i hovedfunksjonen () før utgangen til tilbakeringingsfunksjonen leses (fortsatt i hovedfunksjonen) funksjonen). Følgende kode illustrerer dette:

#inkludere

ved hjelp av navneområdetimer;

røye *produksjon;


tomromcb(røyeute[])

{

produksjon=ute;

}



tomrommainFn(røyeinput[],tomrom (*ptr)(røye[femti]))

{

(*ptr)(input);

koste<<'hovedfunksjon'<<' n';

}


tomromfn()

{

koste<<'sett'<<' n';

}


inthoved-()

{

røyeinput[] = 'tilbakeringingsfunksjon';

tomrom (*ptr)(røye[]) = &cb;

mainFn(input, cb);

fn();

koste<<produksjon<<' n';



komme tilbake 0;

}

Programutgangen er:

hovedfunksjon

sett

tilbakeringingsfunksjon

I denne koden er utgangs- og inngangsdatoen tilfeldigvis det samme nullpunktet. Resultatet av det tredje funksjonsanropet i hovedfunksjonen () har blitt vist før resultatet av tilbakeringingsfunksjonen. Tilbakekallingsfunksjonen ble utført, ferdig og tilordnet resultatet (verdien) til variabelen output, slik at programmet kunne fortsette uten forstyrrelser. I hovedfunksjonen () ble utgangen fra tilbakeringingsfunksjonen brukt (lest og vist) når den var nødvendig, noe som førte til asynkron oppførsel for hele opplegget.

Dette er den enkeltrådede måten å få tilbakekallingsfunksjon asynkron oppførsel med ren C ++.

Grunnleggende bruk av det fremtidige biblioteket

Tanken med det asynkrone tilbakeringingsfunksjonsskjemaet er at hovedfunksjonen returnerer før tilbakeringingsfunksjonen kommer tilbake. Dette ble gjort indirekte, effektivt, i koden ovenfor.

Legg merke til fra koden ovenfor at tilbakeringingsfunksjonen mottar hovedinngangen for koden og produserer hovedutgangen for koden. C ++ - biblioteket, future, har en funksjon som kalles sync (). Det første argumentet til denne funksjonen er tilbakeringingsfunksjonsreferansen; det andre argumentet er input til tilbakeringingsfunksjonen. Sync () -funksjonen returnerer uten å vente på at utførelsen av tilbakeringingsfunksjonen skal fullføres, men lar tilbakeringingsfunksjonen fullføres. Dette gir asynkron oppførsel. Mens tilbakeringingsfunksjonen fortsetter å utføre, siden synkroniseringsfunksjonen () allerede har returnert, fortsetter utsagnene under den. Dette er som ideell asynkron oppførsel.

Programmet ovenfor har blitt skrevet om nedenfor, med tanke på det fremtidige biblioteket og dets synkroniseringsfunksjon ():

#inkludere

#inkludere

#inkludere

ved hjelp av navneområdetimer;

framtid<streng>produksjon;

streng cb(streng stri)

{

komme tilbakestri;

}



tomrommainFn(strenginngang)

{

produksjon=asynk(cb, input);

koste<<'hovedfunksjon'<<' n';

}


tomromfn()

{

koste<<'sett'<<' n';

}


inthoved-()

{

strenginngang=streng('tilbakeringingsfunksjon');

mainFn(input);

fn();

streng ret=produksjon.(); // venter på tilbakeringing for å komme tilbake om nødvendig

koste<<Ikke sant<<' n';



komme tilbake 0;

}

Sync () -funksjonen lagrer endelig utgangen fra tilbakeringingsfunksjonen til det fremtidige objektet. Den forventede utgangen kan oppnås i hovedfunksjonen () ved å bruke get () medlemsfunksjonen til det fremtidige objektet.

Konklusjon

En tilbakeringingsfunksjon er en funksjon, som er et argument, ikke en parameter, i en annen funksjon. Et tilbakeringingsfunksjonsskjema trenger en hovedfunksjon, og selve tilbakeringingsfunksjonen. Erklæringen om tilbakeringingsfunksjonen er en del av parameterlisten til hovedfunksjonen. Definisjonen av tilbakeringingsfunksjonen er angitt i funksjonsanropet til hovedfunksjonen (i main ()). Tilbakekallingsfunksjonen kalles faktisk innenfor definisjonen av hovedfunksjonen.

Et tilbakeringingsfunksjonsskjema er ikke nødvendigvis asynkron. For å være sikker på at tilbakeringingsfunksjonsskjemaet er asynkron, gjør hovedinngangen til koden, inngangen til tilbakeringingsfunksjonen; lage hovedutgangen til koden, utgangen til tilbakeringingsfunksjonen; lagre utdataene fra tilbakeringingsfunksjonen i en variabel eller datastruktur. I hovedfunksjonen (), etter å ha ringt til hovedfunksjonen, utfører du andre uttalelser fra applikasjonen. Når utgangen fra tilbakeringingsfunksjonen er nødvendig, bruker du (leser og viser) den i hovedfunksjonen () der og da.