Fonction de rappel dans C ++

Fonction de rappel dans C ++

Une fonction de rappel est une fonction, qui est un argument, pas un paramètre, dans une autre fonction. L'autre fonction peut être appelée la fonction principale. Donc deux fonctions sont impliquées: la fonction principale et la fonction de rappel elle-même. Dans la liste des paramètres de la fonction principale, la déclaration de la fonction de rappel sans sa définition est présente, tout comme les déclarations d'objets sans affectation sont présentes. La fonction principale est appelée avec des arguments (dans main ()). L'un des arguments de l'appel de fonction principale est la définition efficace de la fonction de rappel. Dans C ++, cet argument est une référence à la définition de la fonction de rappel; Ce n'est pas la définition réelle. La fonction de rappel elle-même est réellement appelée dans la définition de la fonction principale.

La fonction de rappel de base en C ++ ne garantit pas le comportement asynchrone dans un programme. Le comportement asynchrone est le véritable avantage du schéma de fonction de rappel. Dans le schéma de fonction de rappel asynchrone, le résultat de la fonction principale doit être obtenu pour le programme avant que le résultat de la fonction de rappel ne soit obtenu. Il est possible de le faire en C ++; Cependant, C ++ a une bibliothèque appelée Future pour garantir le comportement du schéma de fonction de rappel asynchrone.

Cet article explique le schéma de fonction de rappel de base. Une grande partie est avec Pure C++. En ce qui concerne le rappel, le comportement de base de la future bibliothèque est également expliqué. La connaissance de base de C ++ et de ses pointeurs est nécessaire pour comprendre cet article.

Contenu de l'article

  • Schéma de fonction de rappel de base
  • Comportement synchrone avec fonction de rappel
  • Comportement asynchrone avec fonction de rappel
  • Utilisation de base de la future bibliothèque
  • Conclusion

Schéma de fonction de rappel de base

Un schéma de fonction de rappel a besoin d'une fonction principale, et la fonction de rappel elle-même. La déclaration de la fonction de rappel fait partie de la liste des paramètres de la fonction principale. La définition de la fonction de rappel est indiquée dans l'appel de la fonction de la fonction principale. La fonction de rappel est en fait appelée dans la définition de la fonction principale. Le programme suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
int Principalfn (char ch [], int (* ptr) (int))

int id1 = 1;
int id2 = 2;
int irr = (* ptr) (id2);
couter<<"principal function: "<<
id1<<"<retour id1;

int cb (int iden)

couter<<"callback function"<<'\n';
retour d'iden;

int main()

int (* ptr) (int) = &cb;
char cha [] = "et";
Principalfn (Cha, CB);
retour 0;

La sortie est:

fonction de rappel
Fonction principale: 1 et 2

La fonction principale est identifiée par le principalfn (). La fonction de rappel est identifiée par CB (). La fonction de rappel est définie en dehors de la fonction principale mais réellement appelée dans la fonction principale.

Notez la déclaration de la fonction de rappel comme paramètre dans la liste des paramètres de la déclaration de fonction principale. La déclaration de la fonction de rappel est «int (* ptr) (int)». Notez l'expression de la fonction de rappel, comme un appel de fonction, dans la définition de la fonction principale; Tout argument pour l'appel de la fonction de rappel y est passé. L'instruction pour cet appel de fonction est:

int irr = (* ptr) (id2);

Où id2 est un argument. PTR fait partie du paramètre, un pointeur, qui sera lié à la référence de la fonction de rappel dans la fonction principale ().

Notez l'expression:

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

Dans la fonction Main (), qui relie la déclaration (sans définition) de la fonction de rappel au nom de la définition de la même fonction de rappel.

La fonction principale est appelée, dans la fonction principale (), comme:

Principalfn (Cha, CB);

Où le cha est une chaîne et CB est le nom de la fonction de rappel sans aucun de son argument.

Comportement synchrone de la fonction de rappel

Considérez le programme suivant:

#inclure
Utilisation de Namespace Std;
void PrincipalFn (void (* ptr) ())

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

void CB ()

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

void fn ()

couter<<"seen"<<'\n';

int main()

void (* ptr) () = &cb;
Principalfn (CB);
fn ();
retour 0;

La sortie est:

fonction principale
fonction de rappel
vu

Il y a une nouvelle fonction ici. Toute la nouvelle fonction, c'est d'afficher la sortie, «vu». Dans la fonction principale (), la fonction principale est appelée, alors la nouvelle fonction, fn () est appelée. La sortie montre que le code de la fonction principale a été exécuté, alors que la fonction de rappel a été exécutée, et enfin que pour la fonction fn () a été exécutée. C'est un comportement synchrone (unique).

S'il s'agissait d'un comportement asynchrone, lorsque trois segments de code sont appelés dans l'ordre, le premier segment de code peut être exécuté, suivi à la place par l'exécution du troisième segment de code, avant que le deuxième segment de code ne soit exécuté.

Eh bien, la fonction, fn () peut être appelée à partir de la définition de la fonction principale, plutôt que de la fonction principale (), comme suit:

#inclure
Utilisation de Namespace Std;
void fn ()

couter<<"seen"<<'\n';

void PrincipalFn (void (* ptr) ())

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

void CB ()

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

int main()

void (* ptr) () = &cb;
Principalfn (CB);
retour 0;

La sortie est:

fonction principale
vu
fonction de rappel

Ceci est une imitation du comportement asynchrone. Ce n'est pas un comportement asynchrone. C'est encore un comportement synchrone.

De plus, l'ordre d'exécution du segment de code de la fonction principale et le segment de code de la fonction de rappel peuvent être échangés dans la définition de la fonction principale. Le programme suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
void PrincipalFn (void (* ptr) ())

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

void CB ()

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

void fn ()

couter<<"seen"<<'\n';

int main()

void (* ptr) () = &cb;
Principalfn (CB);
fn ();
retour 0;

La sortie est maintenant,

fonction de rappel
fonction principale
vu

C'est aussi une imitation du comportement asynchrone. Ce n'est pas un comportement asynchrone. C'est encore un comportement synchrone. Le vrai comportement asynchrone peut être obtenu comme expliqué dans la section suivante ou avec la bibliothèque, futur.

Comportement asynchrone avec fonction de rappel

Le pseudo-code pour le schéma de fonction de rappel asynchrone de base est:

type de sortie;
Type CB (sortie de type)

// déclarations

Type PrincipalFn (Type Entrée, Type CB (Type Sortie))

// déclarations

Notez les positions des données d'entrée et de sortie dans les différents endroits du pseudo-code. L'entrée de la fonction de rappel est sa sortie. Les paramètres de la fonction principale sont le paramètre d'entrée du code général et le paramètre de la fonction de rappel. Avec ce schéma, une troisième fonction peut être exécutée (appelée) dans la fonction principale () avant que la sortie de la fonction de rappel ne soit lue (toujours dans la fonction principale ()). Le code suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
sortie de char *;
void CB (Char Out [])

sortie = out;

void PrincipalFn (char de char [], void (* ptr) (char [50]))

(* ptr) (entrée);
couter<<"principal function"<<'\n';

void fn ()

couter<<"seen"<<'\n';

int main()

char char [] = "fonction de rappel";
void (* ptr) (char []) = &cb;
PrincipalFn (entrée, CB);
fn ();
couter<retour 0;

La sortie du programme est:

fonction principale
vu
fonction de rappel

Dans ce code particulier, la sortie de sortie et d'entrée se trouve être la même donnée. Le résultat du troisième appel de fonction dans la fonction principale () a été affiché avant le résultat de la fonction de rappel. La fonction de rappel exécutée, terminée et attribuée son résultat (valeur) à la variable, sortie, permettant au programme de se poursuivre sans son interférence. Dans la fonction principale (), la sortie de la fonction de rappel a été utilisée (lire et afficher) lorsqu'elle était nécessaire, conduisant à un comportement asynchrone pour l'ensemble du schéma.

Ceci est le moyen unique pour obtenir une fonction de rappel de rappel Asynchrones avec pur c pur++.

Utilisation de base de la future bibliothèque

L'idée du schéma de fonction de rappel asynchrone est que la fonction principale renvoie avant que la fonction de rappel ne renvoie. Cela a été fait indirectement, effectivement, dans le code ci-dessus.

Remarque à partir du code ci-dessus que la fonction de rappel reçoit l'entrée principale du code et produit la sortie principale du code. La bibliothèque C ++, Future, a une fonction appelée sync (). Le premier argument de cette fonction est la référence de la fonction de rappel; Le deuxième argument est l'entrée de la fonction de rappel. La fonction sync () revient sans attendre que l'exécution de la fonction de rappel se termine mais permet à la fonction de rappel de terminer. Cela fournit un comportement asynchrone. Alors que la fonction de rappel continue de s'exécuter, puisque la fonction sync () est déjà retournée, les instructions en dessous continuent d'exécuter. C'est comme un comportement asynchrone idéal.

Le programme ci-dessus a été réécrit ci-dessous, en tenant compte de la Future Library et de sa fonction Sync ():

#inclure
#inclure
#inclure
Utilisation de Namespace Std;
avenir sortir;
String CB (String stri)

retour stri;

void principalfn (entrée de chaîne)

Output = async (CB, entrée);
couter<<"principal function"<<'\n';

void fn ()

couter<<"seen"<<'\n';

int main()

String input = String ("Fonction de rappel");
PrincipalFn (entrée);
fn ();
String ret = sortie.obtenir(); // attend que le rappel revienne si nécessaire
couter<retour 0;

La fonction sync () stocke enfin la sortie de la fonction de rappel dans l'objet futur. La sortie attendue peut être obtenue dans la fonction principale (), en utilisant la fonction de membre get () de l'objet futur.

Conclusion

Une fonction de rappel est une fonction, qui est un argument, pas un paramètre, dans une autre fonction. Un schéma de fonction de rappel a besoin d'une fonction principale, et la fonction de rappel elle-même. La déclaration de la fonction de rappel fait partie de la liste des paramètres de la fonction principale. La définition de la fonction de rappel est indiquée dans l'appel de fonction de la fonction principale (dans main ()). La fonction de rappel est en fait appelée dans la définition de la fonction principale.

Un schéma de fonction de rappel n'est pas nécessairement asynchrone. Pour être sûr que le schéma de fonction de rappel est asynchrone, faites l'entrée principale du code, l'entrée de la fonction de rappel; faire la sortie principale du code, la sortie de la fonction de rappel; Stockez la sortie de la fonction de rappel dans une variable ou une structure de données. Dans la fonction principale (), après avoir appelé la fonction principale, exécutez d'autres instructions de l'application. Lorsque la sortie de la fonction de rappel est nécessaire, dans la fonction principale (), utilisez-le (lire et afficher).