C ++

Återuppringningsfunktion i C ++

Återuppringningsfunktion i C ++

En återuppringningsfunktion är en funktion, som är ett argument, inte en parameter, i en annan funktion. Den andra funktionen kan kallas huvudfunktionen. Så två funktioner är inblandade: huvudfunktionen och själva återuppringningsfunktionen. I parameterlistan för huvudfunktionen finns deklarationen för återuppringningsfunktionen utan dess definition, precis som objektdeklarationer utan tilldelning finns. Huvudfunktionen kallas med argument (i huvud ()). Ett av argumenten i huvudfunktionsanropet är den effektiva definitionen av återuppringningsfunktionen. I C ++ är detta argument en hänvisning till definitionen av återuppringningsfunktionen. det är inte den faktiska definitionen. Återuppringningsfunktionen i sig kallas faktiskt inom definitionen av huvudfunktionen.

Den grundläggande återuppringningsfunktionen i C ++ garanterar inte asynkront beteende i ett program.  Asynkront beteende är den verkliga fördelen med återuppringningsfunktionsschemat. I det asynkrona återuppringningsfunktionsschemat bör resultatet av huvudfunktionen erhållas för programmet innan resultatet av återuppringningsfunktionen erhålls. Det är möjligt att göra detta i C ++; emellertid har C ++ ett bibliotek som heter framtida för att garantera beteendet hos det asynkrona återuppringningsfunktionsschemat.

Den här artikeln förklarar det grundläggande återuppringningsfunktionsschemat. Mycket av det är med ren C++. När det gäller återuppringningen förklaras också det framtida biblioteks grundläggande beteende. Grundläggande kunskaper om C ++ och dess pekare är nödvändiga för att förstå den här artikeln.

Artikelinnehåll

Grundläggande system för återuppringning

Ett system för återuppringningsfunktion behöver en huvudfunktion och själva återuppringningsfunktionen. Deklarationen av återuppringningsfunktionen är en del av parameterlistan för huvudfunktionen. Definitionen av återuppringningsfunktionen indikeras i huvudanropets funktionsanrop. Återuppringningsfunktionen kallas faktiskt inom definitionen av huvudfunktionen. Följande program illustrerar detta:

#omfatta
använder namnrymd std;
int principFn (char ch [], int (* ptr) (int))

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

int cb (int iden)

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

int main ()

int (* ptr) (int) = &cb;
char cha [] = "och";
principFn (cha, cb);
returnera 0;

Utgången är:

återuppringningsfunktion
huvudfunktion: 1 och 2

Huvudfunktionen identifieras av principalFn (). Återuppringningsfunktionen identifieras av cb (). Återuppringningsfunktionen definieras utanför huvudfunktionen men kallas faktiskt inom huvudfunktionen.

Notera deklarationen av återuppringningsfunktionen som en parameter i parametarlistan för huvudfunktionsdeklarationen. Deklarationen för återuppringningsfunktionen är “int (* ptr) (int)”. Notera återkallningsfunktionsuttrycket, som ett funktionsanrop, i definitionen av huvudfunktionen; något argument för återuppringningsfunktionssamtalet skickas där. Uttalandet för detta funktionsanrop är:

int idr = (* ptr) (id2);

Där id2 är ett argument. ptr är en del av parametern, en pekare, som kommer att länkas till referensen för återuppringningsfunktionen i huvudfunktionen ().

Notera uttrycket:

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

I huvudfunktionen (), som länkar deklarationen (utan definition) för återuppringningsfunktionen till namnet på definitionen av samma återuppringningsfunktion.

Huvudfunktionen kallas i huvudfunktionen () som:

principFn (cha, cb);

Där cha är en sträng och cb är namnet på återuppringningsfunktionen utan något av dess argument.

Synkron beteende för återuppringningsfunktion

Tänk på följande program:

#omfatta
använder namnrymd std;
ogiltig principFn (ogiltig (* ptr) ())

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

ogiltig cb ()

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

ogiltigt fn ()

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

int main ()

ogiltigt (* ptr) () = &cb;
principFn (cb);
fn ();
returnera 0;

Utgången är:

huvudfunktion
återuppringningsfunktion
sett

Det finns en ny funktion här. Allt som den nya funktionen gör är att visa utgången "sett". I huvudfunktionen () kallas huvudfunktionen, sedan kallas den nya funktionen, fn (). Utgången visar att koden för huvudfunktionen utfördes, sedan för återuppringningsfunktionen och slutligen för fn () -funktionen exekverades. Detta är synkron (enkel tråd) beteende.

Om det var asynkront beteende, när tre kodsegment anropas i ordning, kan det första kodsegmentet köras, följt istället av körningen av det tredje kodsegmentet innan det andra kodsegmentet körs.

Tja, funktionen, fn () kan anropas från definitionen av huvudfunktionen istället för från huvudfunktionen () enligt följande:

#omfatta
använder namnrymd std;
ogiltigt fn ()

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

ogiltig principFn (ogiltig (* ptr) ())

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

ogiltig cb ()

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

int main ()

ogiltigt (* ptr) () = &cb;
principFn (cb);
returnera 0;

Utgången är:

huvudfunktion
sett
återuppringningsfunktion

Detta är en imitation av asynkront beteende. Det är inte asynkront beteende. Det är fortfarande synkront beteende.

Dessutom kan ordningen på exekvering av kodsegmentet för huvudfunktionen och kodsegmentet för återuppringningsfunktionen bytas ut i definitionen av huvudfunktionen. Följande program illustrerar detta:

#omfatta
använder namnrymd std;
 
ogiltig principFn (ogiltig (* ptr) ())

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

ogiltig cb ()

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

ogiltigt fn ()

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

int main ()

ogiltigt (* ptr) () = &cb;
principFn (cb);
fn ();
returnera 0;

Resultatet är nu,

återuppringningsfunktion
huvudfunktion
sett

Detta är också en imitation av asynkront beteende. Det är inte asynkront beteende. Det är fortfarande synkront beteende. Verkligt asynkront beteende kan erhållas enligt förklaringen i nästa avsnitt eller med biblioteket, framtiden.

Asynkron beteende med återuppringningsfunktion

Pseudokoden för det grundläggande asynkrona återuppringningsfunktionsschemat är:

typ utdata;
typ cb (typutgång)

// uttalanden

typ principFn (typinmatning, typ cb (typutgång))

// uttalanden

Notera positionerna för in- och utdata på de olika platserna i pseudokoden. Ingången till återuppringningsfunktionen är dess utgång. Parametrarna för huvudfunktionen är ingångsparametern för den allmänna koden och parametern för återuppringningsfunktionen. Med detta schema kan en tredje funktion utföras (kallas) i huvudfunktionen () innan utgången från återuppringningsfunktionen läses (fortfarande i huvudfunktionen (). Följande kod illustrerar detta:

#omfatta
använder namnrymd std;
char * output;
void cb (char out [])

utgång = ut;

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

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

ogiltigt fn ()

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

int main ()

char input [] = "återuppringningsfunktion";
ogiltigt (* ptr) (char []) = &cb;
principalFn (input, cb);
fn ();
cout<returnera 0;

Programutgången är:

huvudfunktion
sett
återuppringningsfunktion

I denna speciella kod råkar utgångs- och ingångsdatum vara samma datum. Resultatet av det tredje funktionsanropet i huvudfunktionen () har visats före resultatet av återuppringningsfunktionen. Återuppringningsfunktionen utfördes, avslutades och tilldelade sitt resultat (värde) till variabeln, output, så att programmet kan fortsätta utan dess störning. I huvudfunktionen () användes utgången från återuppringningsfunktionen (läst och visad) när den behövdes, vilket ledde till asynkront beteende för hela schemat.

Detta är det enkeltrådade sättet att få asynkront återuppringningsfunktion med rent C++.

Grundläggande användning av det framtida biblioteket

Tanken med det asynkrona återuppringningsfunktionsschemat är att huvudfunktionen återvänder innan återuppringningsfunktionen återvänder. Detta gjordes indirekt, effektivt, i ovanstående kod.

Observera från ovanstående kod att återuppringningsfunktionen tar emot huvudingången för koden och producerar huvudutgången för koden. C ++ - biblioteket, framtiden, har en funktion som heter sync (). Det första argumentet för denna funktion är återuppringningsfunktionsreferensen; det andra argumentet är ingången till återuppringningsfunktionen. Sync () -funktionen återvänder utan att vänta på att exekveringen av återuppringningsfunktionen ska slutföras men tillåter återuppringningsfunktionen att slutföra. Detta ger asynkront beteende. Medan återuppringningsfunktionen fortsätter att köras, eftersom sync () -funktionen redan har återvänt, fortsätter påståendena nedan. Detta är som idealiskt asynkront beteende.

Ovanstående program har skrivits om nedan med beaktande av det framtida biblioteket och dess sync () -funktion:

#omfatta
#omfatta
#omfatta
använder namnrymd std;
framtida produktion;
sträng cb (sträng stri)

retur stri;

void principalFn (stränginmatning)

output = async (cb, input);
cout<<"principal function"<<'\n';

ogiltigt fn ()

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

int main ()

stränginmatning = sträng ("återuppringningsfunktion");
principalFn (input);
fn ();
string ret = output.skaffa sig(); // väntar på att återuppringning återkommer vid behov
cout<returnera 0;

Sync () -funktionen lagrar slutligen utgången från återuppringningsfunktionen i det framtida objektet. Den förväntade utgången kan erhållas i huvudfunktionen () med hjälp av get () medlemsfunktionen för det framtida objektet.

Slutsats

En återuppringningsfunktion är en funktion, som är ett argument, inte en parameter, i en annan funktion. Ett återuppringningsfunktionsschema behöver en huvudfunktion och själva återuppringningsfunktionen. Deklarationen av återuppringningsfunktionen är en del av parameterlistan för huvudfunktionen. Definitionen av återuppringningsfunktionen anges i funktionsanropet för huvudfunktionen (i huvud ()). Återuppringningsfunktionen kallas faktiskt inom definitionen av huvudfunktionen.

Ett återuppringningsfunktionsschema är inte nödvändigtvis asynkront. För att vara säker på att återuppringningsfunktionsschemat är asynkront, gör huvudinmatningen till koden, inmatningen till återuppringningsfunktionen; gör kodens huvudutgång, utgången från återuppringningsfunktionen; lagra utdata från återuppringningsfunktionen i en variabel eller datastruktur. I huvudfunktionen (), efter att ha anropat huvudfunktionen, kör du andra uttalanden i applikationen. När utdata från återuppringningsfunktionen behövs, använd (läs och vis) i huvudfunktionen () där och då.

Mus Topp 5 Ergonomiska datormusprodukter för Linux
Topp 5 Ergonomiska datormusprodukter för Linux
Ger långvarig datoranvändning smärta i handleden eller fingrarna? Lider du av styva leder och måste ständigt skaka hand? Känner du en brännande smärta...
Mus Så här ändrar du inställningar för mus och pekplatta med Xinput i Linux
Så här ändrar du inställningar för mus och pekplatta med Xinput i Linux
De flesta Linux-distributioner levereras med "libinput" -bibliotek som standard för att hantera inmatningshändelser i ett system. Den kan bearbeta inm...
Mus Omforma dina musknappar på olika sätt för olika program med X-Mouse Button Control
Omforma dina musknappar på olika sätt för olika program med X-Mouse Button Control
Kanske behöver du ett verktyg som kan göra att musens kontroll ändras med alla applikationer som du använder. Om så är fallet kan du prova en ansökan ...