Una función de devolución de llamada es una función, que es un argumento, no un parámetro, en otra función. La otra función se puede llamar función principal. Entonces, hay dos funciones involucradas: la función principal y la función de devolución de llamada en sí. En la lista de parámetros de la función principal, la declaración de la función de devolución de llamada sin su definición está presente, al igual que las declaraciones de objeto sin asignación están presentes. La función principal se llama con argumentos (en main ()). Uno de los argumentos en la llamada a la función principal es la definición efectiva de la función de devolución de llamada. En C ++, este argumento es una referencia a la definición de la función de devolución de llamada; no es la definición real. La función de devolución de llamada en sí misma se llama dentro de la definición de la función principal.
La función de devolución de llamada básica en C ++ no garantiza un comportamiento asincrónico en un programa. El comportamiento asincrónico es el beneficio real del esquema de la función de devolución de llamada. En el esquema de función de devolución de llamada asincrónica, el resultado de la función principal debe obtenerse para el programa antes de que se obtenga el resultado de la función de devolución de llamada. Es posible hacer esto en C ++; sin embargo, C ++ tiene una biblioteca llamada future para garantizar el comportamiento del esquema de función de devolución de llamada asincrónica.
Este artículo explica el esquema básico de la función de devolución de llamada. Mucho es con puro C++. En lo que respecta a la devolución de llamada, también se explica el comportamiento básico de la biblioteca futura. Se necesitan conocimientos básicos de C ++ y sus punteros para comprender este artículo.
Contenido del artículo
- Esquema básico de la función de devolución de llamada
- Comportamiento síncrono con función de devolución de llamada
- Comportamiento asincrónico con función de devolución de llamada
- Uso básico de la futura biblioteca
- Conclusión
Esquema básico de la función de devolución de llamada
Un esquema de función de devolución de llamada necesita una función principal y la función de devolución de llamada en sí. La declaración de la función de devolución de llamada es parte de la lista de parámetros de la función principal. La definición de la función de devolución de llamada se indica en la llamada de función de la función principal. La función de devolución de llamada se llama en realidad dentro de la definición de la función principal. El siguiente programa ilustra esto:
#incluirusando el espacio de nombres std;
int principalFn (char ch [], int (* ptr) (int))
int id1 = 1;
int id2 = 2;
int idr = (* ptr) (id2);
cout<<"principal function: "<
int cb (int iden)
cout<<"callback function"<<'\n';
volver iden;
int main ()
int (* ptr) (int) = &cb;
char cha [] = "y";
principalFn (cha, cb);
return 0;
La salida es:
función de devolución de llamadafunción principal: 1 y 2
La función principal está identificada por principalFn (). La función de devolución de llamada se identifica mediante cb (). La función de devolución de llamada se define fuera de la función principal, pero en realidad se llama dentro de la función principal.
Tenga en cuenta la declaración de la función de devolución de llamada como un parámetro en la lista de parámetros de la declaración de la función principal. La declaración de la función de devolución de llamada es "int (* ptr) (int)". Tenga en cuenta la expresión de la función de devolución de llamada, como una llamada de función, en la definición de la función principal; cualquier argumento para la llamada a la función de devolución de llamada se pasa allí. La declaración para esta llamada de función es:
int idr = (* ptr) (id2);Donde id2 es un argumento. ptr es parte del parámetro, un puntero, que se vinculará a la referencia de la función de devolución de llamada en la función main ().
Note la expresión:
int (* ptr) (int) = &cb;En la función main (), que vincula la declaración (sin definición) de la función de devolución de llamada al nombre de la definición de la misma función de devolución de llamada.
La función principal se llama, en la función main (), como:
principalFn (cha, cb);Donde cha es una cadena y cb es el nombre de la función de devolución de llamada sin ninguno de sus argumentos.
Comportamiento síncrono de la función de devolución de llamada
Considere el siguiente programa:
#incluirusando el espacio de nombres std;
void principalFn (void (* ptr) ())
cout<<"principal function"<<'\n';
(* ptr) ();
vacío cb ()
cout<<"callback function"<<'\n';
vacío fn ()
cout<<"seen"<<'\n';
int main ()
vacío (* ptr) () = &cb;
principalFn (cb);
fn ();
return 0;
La salida es:
función principalfunción de devolución de llamada
visto
Hay una nueva función aquí. Lo único que hace la nueva función es mostrar la salida, "visto". En la función main (), se llama a la función principal, luego se llama a la nueva función, fn (). La salida muestra que se ejecutó el código de la función principal, luego se ejecutó el de la función de devolución de llamada y finalmente se ejecutó el de la función fn (). Este es un comportamiento sincrónico (de un solo subproceso).
Si fuera un comportamiento asincrónico, cuando se llaman tres segmentos de código en orden, se puede ejecutar el primer segmento de código, seguido en su lugar por la ejecución del tercer segmento de código, antes de que se ejecute el segundo segmento de código.
Bueno, la función, fn () se puede llamar desde dentro de la definición de la función principal, en lugar de desde dentro de la función main (), de la siguiente manera:
#incluirusando el espacio de nombres std;
vacío fn ()
cout<<"seen"<<'\n';
void principalFn (void (* ptr) ())
cout<<"principal function"<<'\n';
fn ();
(* ptr) ();
vacío cb ()
cout<<"callback function"<<'\n';
int main ()
vacío (* ptr) () = &cb;
principalFn (cb);
return 0;
La salida es:
función principalvisto
función de devolución de llamada
Esta es una imitación del comportamiento asincrónico. No es un comportamiento asincrónico. Sigue siendo un comportamiento sincrónico.
Además, el orden de ejecución del segmento de código de la función principal y el segmento de código de la función de devolución de llamada se puede intercambiar en la definición de la función principal. El siguiente programa ilustra esto:
#incluirusando el espacio de nombres std;
void principalFn (void (* ptr) ())
(* ptr) ();
cout<<"principal function"<<'\n';
vacío cb ()
cout<<"callback function"<<'\n';
vacío fn ()
cout<<"seen"<<'\n';
int main ()
vacío (* ptr) () = &cb;
principalFn (cb);
fn ();
return 0;
La salida es ahora,
función de devolución de llamadafunción principal
visto
Esto también es una imitación del comportamiento asincrónico. No es un comportamiento asincrónico. Sigue siendo un comportamiento sincrónico. El verdadero comportamiento asincrónico se puede obtener como se explica en la siguiente sección o con la biblioteca, futuro.
Comportamiento asincrónico con función de devolución de llamada
El pseudocódigo para el esquema de función de devolución de llamada asíncrona básica es:
tipo de salida;tipo cb (tipo de salida)
//declaraciones
type principalFn (escriba entrada, escriba cb (escriba salida))
//declaraciones
Tenga en cuenta las posiciones de los datos de entrada y salida en los diferentes lugares del pseudocódigo. La entrada de la función de devolución de llamada es su salida. Los parámetros de la función principal son el parámetro de entrada para el código general y el parámetro para la función de devolución de llamada. Con este esquema, se puede ejecutar (llamar) una tercera función en la función main () antes de que se lea la salida de la función de devolución de llamada (aún en la función main ()). El siguiente código ilustra esto:
#incluirusando el espacio de nombres std;
char * salida;
void cb (char hacia fuera [])
salida = fuera;
void principalFn (char input [], void (* ptr) (char [50]))
(* ptr) (entrada);
cout<<"principal function"<<'\n';
vacío fn ()
cout<<"seen"<<'\n';
int main ()
char input [] = "función de devolución de llamada";
void (* ptr) (char []) = &cb;
principalFn (entrada, cb);
fn ();
cout<