Uma função de retorno de chamada é uma função, que é um argumento, não um parâmetro, em outra função. A outra função pode ser chamada de função principal. Portanto, duas funções estão envolvidas: a função principal e a própria função de retorno de chamada. Na lista de parâmetros da função principal, a declaração da função de retorno de chamada sem sua definição está presente, assim como as declarações de objeto sem atribuição estão presentes. A função principal é chamada com argumentos (em main ()). Um dos argumentos na chamada da função principal é a definição efetiva da função de retorno de chamada. Em C ++, esse argumento é uma referência à definição da função de retorno de chamada; não é a definição real. A própria função de retorno de chamada é realmente chamada dentro da definição da função principal.
A função de retorno de chamada básica em C ++ não garante comportamento assíncrono em um programa. O comportamento assíncrono é o benefício real do esquema de função de retorno de chamada. No esquema de função de retorno de chamada assíncrona, o resultado da função principal deve ser obtido para o programa antes que o resultado da função de retorno de chamada seja obtido. É possível fazer isso em C ++; no entanto, C ++ tem uma biblioteca chamada future para garantir o comportamento do esquema de função de retorno de chamada assíncrona.
Este artigo explica o esquema básico da função de retorno de chamada. Muito disso é com C puro++. No que diz respeito ao retorno de chamada, o comportamento básico da futura biblioteca também é explicado. O conhecimento básico de C ++ e seus indicadores são necessários para a compreensão deste artigo.
Conteúdo do Artigo
- Esquema de função de retorno de chamada básico
- Comportamento síncrono com função de retorno de chamada
- Comportamento assíncrono com função de retorno de chamada
- Uso básico da futura Biblioteca
- Conclusão
Esquema de função de retorno de chamada básico
Um esquema de função de retorno de chamada precisa de uma função principal, e a própria função de retorno de chamada. A declaração da função de retorno de chamada faz parte da lista de parâmetros da função principal. A definição da função de retorno de chamada é indicada na chamada de função da função principal. A função de retorno de chamada é realmente chamada dentro da definição da função principal. O programa a seguir ilustra isso:
#incluirusando namespace std;
int principalFn (char ch [], int (* ptr) (int))
int id1 = 1;
id2 int = 2;
int idr = (* ptr) (id2);
cout<<"principal function: "<
int cb (int iden)
cout<<"callback function"<<'\n';
return iden;
int main ()
int (* ptr) (int) = &cb;
char cha [] = "e";
principalFn (cha, cb);
return 0;
O resultado é:
função de retorno de chamadafunção principal: 1 e 2
A função principal é identificada por principalFn (). A função de retorno de chamada é identificada por cb (). A função de retorno de chamada é definida fora da função principal, mas na verdade é chamada dentro da função principal.
Observe a declaração da função de retorno de chamada como um parâmetro na lista de parâmetros da declaração da função principal. A declaração da função de retorno de chamada é “int (* ptr) (int)”. Observe a expressão da função de retorno de chamada, como uma chamada de função, na definição da função principal; qualquer argumento para a chamada da função de retorno de chamada é passado lá. A instrução para esta chamada de função é:
int idr = (* ptr) (id2);Onde id2 é um argumento. ptr faz parte do parâmetro, um ponteiro, que será vinculado à referência da função de retorno de chamada na função main ().
Observe a expressão:
int (* ptr) (int) = &cb;Na função main (), que vincula a declaração (sem definição) da função de retorno de chamada ao nome da definição da mesma função de retorno de chamada.
A função principal é chamada, na função main (), como:
principalFn (cha, cb);Onde cha é uma string e cb é o nome da função de retorno de chamada sem nenhum de seus argumentos.
Comportamento síncrono da função de retorno de chamada
Considere o seguinte programa:
#incluirusando namespace std;
void principalFn (void (* ptr) ())
cout<<"principal function"<<'\n';
(* ptr) ();
void cb ()
cout<<"callback function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
void (* ptr) () = &cb;
principalFn (cb);
fn ();
return 0;
O resultado é:
função principalfunção de retorno de chamada
visto
Há uma nova função aqui. Tudo o que a nova função faz é exibir a saída, "visto". Na função main (), a função principal é chamada, então a nova função, fn () é chamada. A saída mostra que o código para a função principal foi executado, depois o da função de retorno de chamada e, finalmente, o da função fn (). Este é um comportamento síncrono (single-threaded).
Se fosse um comportamento assíncrono, quando três segmentos de código são chamados em ordem, o primeiro segmento de código pode ser executado, seguido pela execução do terceiro segmento de código, antes que o segundo segmento de código seja executado.
Bem, a função, fn () pode ser chamada de dentro da definição da função principal, em vez de dentro da função main (), da seguinte maneira:
#incluirusando namespace std;
void fn ()
cout<<"seen"<<'\n';
void principalFn (void (* ptr) ())
cout<<"principal function"<<'\n';
fn ();
(* ptr) ();
void cb ()
cout<<"callback function"<<'\n';
int main ()
void (* ptr) () = &cb;
principalFn (cb);
return 0;
O resultado é:
função principalvisto
função de retorno de chamada
Esta é uma imitação de comportamento assíncrono. Não é um comportamento assíncrono. Ainda é um comportamento síncrono.
Além disso, a ordem de execução do segmento de código da função principal e o segmento de código da função de retorno de chamada podem ser trocados na definição da função principal. O programa a seguir ilustra isso:
#incluirusando namespace std;
void principalFn (void (* ptr) ())
(* ptr) ();
cout<<"principal function"<<'\n';
void cb ()
cout<<"callback function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
void (* ptr) () = &cb;
principalFn (cb);
fn ();
return 0;
A saída é agora,
função de retorno de chamadafunção principal
visto
Isso também é uma imitação do comportamento assíncrono. Não é um comportamento assíncrono. Ainda é um comportamento síncrono. O comportamento assíncrono verdadeiro pode ser obtido conforme explicado na próxima seção ou com a biblioteca, no futuro.
Comportamento assíncrono com função de retorno de chamada
O pseudocódigo para o esquema básico de função de retorno de chamada assíncrona é:
saída de tipo;tipo cb (tipo de saída)
//afirmações
tipo principalFn (tipo de entrada, tipo cb (tipo de saída))
//afirmações
Observe as posições dos dados de entrada e saída nos diferentes lugares do pseudo-código. A entrada da função de retorno de chamada é sua saída. Os parâmetros da função principal são o parâmetro de entrada para o código geral e o parâmetro para a função de retorno de chamada. Com este esquema, uma terceira função pode ser executada (chamada) na função main () antes que a saída da função callback seja lida (ainda na função main ()). O código a seguir ilustra isso:
#incluirusando namespace std;
saída char *;
void cb (char out [])
output = out;
void principalFn (char input [], void (* ptr) (char [50]))
(* ptr) (entrada);
cout<<"principal function"<<'\n';
void fn ()
cout<<"seen"<<'\n';
int main ()
entrada char [] = "função de retorno de chamada";
void (* ptr) (char []) = &cb;
principalFn (entrada, cb);
fn ();
cout<