Funció de devolució de trucada en C ++

Callback Function C



Una funció de devolució de trucada és una funció, que és un argument, no un paràmetre, en una altra funció. L'altra funció es pot anomenar la funció principal. Per tant, hi ha dues funcions: la funció principal i la funció de devolució de trucada. A la llista de paràmetres de la funció principal, hi ha la declaració de la funció de devolució de trucada sense la seva definició, de la mateixa manera que hi ha declaracions d'objectes sense assignació. La funció principal es diu amb arguments (a main ()). Un dels arguments de la trucada a la funció principal és la definició efectiva de la funció de devolució de trucada. A C ++, aquest argument és una referència a la definició de la funció de devolució de trucada; no és la definició real. La funció de devolució de trucada en sí es crida realment dins de la definició de la funció principal.

La funció bàsica de devolució de trucada a C ++ no garanteix un comportament asíncron en un programa. El comportament asíncron és l’avantatge real de l’esquema de funció de devolució de trucada. A l’esquema de funció de devolució de trucada asíncrona, s’hauria d’obtenir el resultat de la funció principal per al programa abans que s’obtingui el resultat de la funció de devolució de trucada. És possible fer-ho en C ++; no obstant això, C ++ té una biblioteca anomenada future per garantir el comportament de l'esquema de funció de devolució de trucada asíncrona.







En aquest article s’explica l’esquema bàsic de la funció de devolució de trucada. Molta part és amb C ++ pur. Pel que fa a la devolució de trucada, també s’explica el comportament bàsic de la futura biblioteca. Els coneixements bàsics de C ++ i els seus indicadors són necessaris per a la comprensió d’aquest article.



Contingut de l'article

Esquema bàsic de funció de devolució de trucada

Un esquema de funció de devolució de trucada necessita una funció principal i la mateixa funció de devolució de trucada. La declaració de la funció de devolució de trucada forma part de la llista de paràmetres de la funció principal. La definició de la funció de devolució de trucada s'indica a la trucada de funció de la funció principal. La funció de devolució de trucada es crida realment dins de la definició de la funció principal. El programa següent ho il·lustra:



#incloure

utilitzant espai de nomshores;



intprincipalFn(charcap[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

intgeneralment= (*ptr)(id2);

cost<<'funció principal:'<<id1<<''<<cap<<''<<generalment<<' n';

tornarid1;

}


intcb(intiden)

{

cost<<'funció de devolució de trucada'<<' n';

tornariden;

}


intprincipal()

{

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

charno[] = 'i';

principalFn(pare, cb);



tornar 0;

}

La sortida és:





funció de devolució de trucada

funció principal: 1 i 2

La funció principal s’identifica amb principalFn (). La funció de devolució de trucada s’identifica amb cb (). La funció de devolució de trucada es defineix fora de la funció principal, però realment es diu dins de la funció principal.

Tingueu en compte la declaració de la funció de devolució de trucada com a paràmetre a la llista de paràmetres de la declaració de funció principal. La declaració de la funció de devolució de trucada és int (* ptr) (int). Tingueu en compte l'expressió de la funció de devolució de trucada, com una trucada de funció, a la definició de la funció principal; allà es passa qualsevol argument per a la funció de devolució de trucada. La sentència d'aquesta trucada de funció és:



intgeneralment= (*ptr)(id2);

On id2 és un argument. ptr forma part del paràmetre, un punter, que estarà enllaçat amb la referència de la funció de devolució de trucada a la funció main ().

Tingueu en compte l’expressió:

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

A la funció main (), que vincula la declaració (sense definició) de la funció de devolució de trucada al nom de la definició de la mateixa funció de devolució de trucada.

La funció principal s'anomena, a la funció main (), com:

principalFn(pare, cb);

On cha és una cadena i cb és el nom de la funció de devolució de trucada sense cap dels seus arguments.

Comportament síncró de la funció de devolució de trucada

Penseu en el programa següent:

#incloure

utilitzant espai de nomshores;



buitprincipalFn(buit (*ptr)())

{

cost<<'funció principal'<<' n';

(*ptr)();

}


buitcb()

{

cost<<'funció de devolució de trucada'<<' n';

}


buitfn()

{

cost<<'vist'<<' n';

}


intprincipal()

{

buit (*ptr)() = &cb;

principalFn(cb);

fn();



tornar 0;

}

La sortida és:

funció principal

funció de devolució de trucada

vist

Aquí hi ha una nova funció. Tot el que fa la nova funció és mostrar la sortida, vista. A la funció main (), s'anomena la funció principal i, a continuació, s'anomena la nova funció, fn (). La sortida mostra que s'ha executat el codi de la funció principal, que s'ha executat el de la funció de devolució de trucada i, finalment, el de la funció fn (). Es tracta d’un comportament síncró (de fil únic).

Si es tractés d'un comportament asíncron, quan es criden tres segments de codi en ordre, es pot executar el primer segment de codi, seguit de l'execució del tercer segment de codi, abans que s'executi el segon segment de codi.

Bé, la funció, fn () es pot cridar des de la definició de la funció principal, en lloc de des de la funció main (), de la següent manera:

#incloure

utilitzant espai de nomshores;



buitfn()

{

cost<<'vist'<<' n';

}


buitprincipalFn(buit (*ptr)())

{

cost<<'funció principal'<<' n';

fn();

(*ptr)();

}


buitcb()

{

cost<<'funció de devolució de trucada'<<' n';

}


intprincipal()

{

buit (*ptr)() = &cb;

principalFn(cb);



tornar 0;

}

La sortida és:

funció principal

vist

funció de devolució de trucada

Es tracta d’una imitació del comportament asíncron. No és un comportament asíncron. Encara és un comportament síncró.

A més, l'ordre d'execució del segment de codi de la funció principal i el segment de codi de la funció de devolució de trucada es poden canviar a la definició de la funció principal. El programa següent ho il·lustra:

#incloure

utilitzant espai de nomshores;



buitprincipalFn(buit (*ptr)())

{

(*ptr)();

cost<<'funció principal'<<' n';

}


buitcb()

{

cost<<'funció de devolució de trucada'<<' n';

}


buitfn()

{

cost<<'vist'<<' n';

}


intprincipal()

{

buit (*ptr)() = &cb;

principalFn(cb);

fn();



tornar 0;

}

La sortida és ara,

funció de devolució de trucada

funció principal

vist

Això també és una imitació del comportament asíncron. No és un comportament asíncron. Encara és un comportament síncró. Es pot obtenir un veritable comportament asíncron tal com s'explica a la secció següent o amb la biblioteca, en el futur.

Comportament asíncron amb funció de devolució de trucada

El pseudocodi de l'esquema bàsic de funció de devolució de trucada asíncrona és:

tipus de sortida;

escriviu cb(tipus de sortida)

{

// declaracions

}


escriviu principalFn(escriviu entrada, escriviu cb(tipus de sortida))

{

// declaracions

}

Tingueu en compte les posicions de les dades d'entrada i sortida als diferents llocs del pseudocodi. L’entrada de la funció de devolució de trucada és la seva sortida. Els paràmetres de la funció principal són el paràmetre d'entrada per al codi general i el paràmetre per a la funció de devolució de trucada. Amb aquest esquema, es pot executar (anomenar) una tercera funció a la funció main () abans de llegir la sortida de la funció de devolució de trucada (encara a la funció main ()). El següent codi ho il·lustra:

#incloure

utilitzant espai de nomshores;

char *sortida;


buitcb(charfora[])

{

sortida=fora;

}



buitprincipalFn(charentrada[],buit (*ptr)(char[50]))

{

(*ptr)(entrada);

cost<<'funció principal'<<' n';

}


buitfn()

{

cost<<'vist'<<' n';

}


intprincipal()

{

charentrada[] = 'funció de devolució de trucada';

buit (*ptr)(char[]) = &cb;

principalFn(entrada, cb);

fn();

cost<<sortida<<' n';



tornar 0;

}

La sortida del programa és:

funció principal

vist

funció de devolució de trucada

En aquest codi concret, la dada de sortida i d’entrada és la mateixa. El resultat de la tercera trucada de funció a la funció main () s'ha visualitzat abans del resultat de la funció de devolució de trucada. La funció de devolució de trucada ha executat, acabat i assignat el seu resultat (valor) a la variable de sortida, cosa que permet al programa continuar sense la seva interferència. A la funció main (), s'utilitzava la sortida de la funció de devolució de trucada (llegida i visualitzada) quan era necessària, cosa que comportava un comportament asíncron per a tot l'esquema.

Aquesta és la manera d'un únic fil per obtenir un comportament asíncron de la funció de devolució de trucada amb C ++ pur.

Ús bàsic de la futura Biblioteca

La idea de l’esquema de funció de devolució de trucada asíncron és que la funció principal torna abans que la funció de devolució de trucada. Això es va fer de manera indirecta, efectiva, al codi anterior.

Tingueu en compte del codi anterior que la funció de devolució de trucada rep l'entrada principal del codi i produeix la sortida principal del codi. La biblioteca C ++, futura, té una funció anomenada sync (). El primer argument d'aquesta funció és la referència a la funció de devolució de trucada; el segon argument és l'entrada de la funció de devolució de trucada. La funció sync () torna sense esperar que finalitzi l'execució de la funció de devolució de trucada, però permet completar la funció de devolució de trucada. Això proporciona un comportament asíncron. Tot i que la funció de devolució de trucada continua executant-se, ja que la funció sync () ja ha tornat, les sentències següents es continuen executant. Això és com un comportament asíncron ideal.

El programa anterior s’ha reescrit a continuació, tenint en compte la futura biblioteca i la seva funció sync ():

#incloure

#incloure

#incloure

utilitzant espai de nomshores;

futur<corda>sortida;

cadena cb(corda stri)

{

tornarstri;

}



buitprincipalFn(entrada de cadena)

{

sortida=asíncron(cb, entrada);

cost<<'funció principal'<<' n';

}


buitfn()

{

cost<<'vist'<<' n';

}


intprincipal()

{

entrada de cadena=corda('funció de devolució de trucada');

principalFn(entrada);

fn();

ret de cadena=sortida.aconseguir(); // espera que es torni la devolució de trucada si cal

cost<<dret<<' n';



tornar 0;

}

La funció sync () emmagatzema finalment la sortida de la funció de devolució de trucada a l'objecte futur. La sortida esperada es pot obtenir a la funció main (), mitjançant la funció de membre get () de l'objecte futur.

Conclusió

Una funció de devolució de trucada és una funció, que és un argument, no un paràmetre, en una altra funció. Un esquema de funció de devolució de trucada necessita una funció principal i la mateixa funció de devolució de trucada. La declaració de la funció de devolució de trucada forma part de la llista de paràmetres de la funció principal. La definició de la funció de devolució de trucada s'indica a la trucada de funció de la funció principal (a main ()). La funció de devolució de trucada es crida realment dins de la definició de la funció principal.

Un esquema de funció de devolució de trucada no és necessàriament asíncron. Per assegurar-vos que l'esquema de la funció de devolució de trucada és asíncron, feu l'entrada principal del codi, l'entrada de la funció de devolució de trucada; fer la sortida principal del codi, la sortida de la funció de devolució de trucada; emmagatzemar la sortida de la funció de devolució de trucada en una variable o estructura de dades. A la funció main (), després de cridar a la funció principal, executeu altres sentències de l'aplicació. Quan calgui la sortida de la funció de devolució de trucada, a la funció main (), utilitzeu-la (llegiu-la i visualitzeu-la) allà i després.