Passer des fonctions membres de classe en tant que rappels
En programmation orientée objet, il est parfois nécessaire de transmettre une fonction membre de classe en tant que rappel à une API externe. Cependant, tenter cela directement peut rencontrer des erreurs de compilation, comme démontré dans le scénario suivant :
m_cRedundencyManager->Init(this->RedundancyManagerCallBack);
Le compilateur se plaint d'une liste d'arguments manquante pour le pointeur de fonction, suggérant l'utilisation de &CLoggersInfra::RedundancyManagerCallBack à la place. Cependant, cela ne parvient toujours pas à se compiler.
Comprendre les fonctions membres
Avant d'approfondir la solution, il est crucial de comprendre la véritable nature des fonctions membres. En C , les fonctions membres sont essentiellement des fonctions régulières qui possèdent un paramètre caché supplémentaire : this. Ce paramètre masqué représente l'instance d'objet à laquelle appartient la fonction.
Considérons l'exemple suivant :
class A { public: int data; void foo(int addToData) { data += addToData; } };
La fonction A::foo prend un paramètre, mais en interne, elle fonctionne avec deux paramètres : addToData et ceci. Ce dernier pointe vers l'objet A pour lequel foo est appelé. Ce comportement est implicite lors de l'utilisation de la syntaxe de fonction membre an_a_object.foo(5). Syntaxiquement, le compilateur traduit cela par A::foo(&an_a_object, 5).
Le problème avec les rappels
Revenant au problème d'origine, la fonction Init de l'API attend un pointeur de fonction qui prend un seul paramètre. Cependant, les fonctions membres de la classe telles que CLoggersInfra::RedundancyManagerCallBack nécessitent par nature deux paramètres, y compris le paramètre this masqué. Cette incompatibilité conduit à l'erreur de compilation.
Solution : liaison avec les fonctions Boost ou Lambda
La solution conventionnelle consiste à lier la fonction membre à une instance de classe spécifique à l'aide du boost de Boost ::bind ou les fonctions lambda de C 11.
Avec boost::bind, on peut créer une nouvelle fonction qui prend le paramètres requis en "verrouillant" ce paramètre masqué sur une instance d'objet spécifique. Cette nouvelle fonction peut ensuite être transmise comme rappel.
#include <boost/bind.hpp> auto bound_callback = boost::bind(&CLoggersInfra::RedundencyManagerCallBack, this); Init(boost::function<void()>(bound_callback));
C 11 propose des fonctions lambda comme alternative plus simple à boost::bind. Les fonctions Lambda peuvent également capturer le pointeur this, permettant une liaison de rappel concise :
auto lambda_callback = [this]() { RedundancyManagerCallBack(); }; Init(std::function<void()>(lambda_callback));
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!