Comment puis-je mettre en œuvre un rappel en C++?
Je veux implémenter une classe en c++, qui a une fonction de rappel.
Donc je pense que j'ai besoin d'une méthode qui a 2 arguments:
- l'objet cible. (disons
*myObj) - le pointeur vers une fonction membre de
l'objet cible. (afin que je puisse faire
*myObj->memberFunc(); )
Les conditions sont les suivantes:
- myObj peut être de toute la classe.
- la fonction membre qui va être la fonction de rappel est non statique.
J'ai lu à ce sujet, mais il semble que j'ai besoin de connaître la classe de myObj avant de la main. Mais je ne suis pas sûr de savoir comment faire. Comment puis-je gérer cela? Est-ce possible en C++?
C'est quelque chose que j'ai à l'esprit, mais est certainement incorrecte.
class MyClassWithCallback{
public
void *targetObj;
void (*callback)(int number);
void setCallback(void *myObj, void(*callbackPtr)(int number)){
targetObj = myObj;
callback = callbackPtr;
};
void callCallback(int a){
(myObj)->ptr(a);
};
};
class Target{
public
int res;
void doSomething(int a){//so something here. This is gonna be the callback function};
};
int main(){
Target myTarget;
MyClassWithCallback myCaller;
myCaller.setCallback((void *)&myTarget, &doSomething);
}
J'apprécie toute l'aide.
Merci.
Mise à JOUR
La plupart d'entre vous a dit de les Observer et de Délégation, bien que j'ai exactement ce que je recherche, je suis une sorte d'Objective-C/Cocoa d'esprit du mec.
Mon actuel de la mise en œuvre est l'utilisation des interfaces avec les fonctions virtuelles. Est juste que je pensais que ce serait plus "intelligents" juste à passer de l'objet et un membre de pointeur de fonction (comme boost!) au lieu de définir une Interface. Mais Il semble que tout le monde accepte que les Interfaces sont le moyen le plus facile à droite? Boost semble être une bonne idée, (en supposant que est installé)
function
et bind
au lieu d'interfaces. Notez également que si vous utilisez version récente de gcc, vous avez déjà function
et bind
donc pas besoin de coup de pouce. À l'aide de la fonction/bind est fonctionnelle la programmation des modèles tout en utilisant des interfaces est plus à l'aide de "standard" modèle de conception qui a un sens différentOriginalL'auteur nacho4d | 2010-08-01
Vous devez vous connecter pour publier un commentaire.
La meilleure solution, utiliser
boost::function
avecboost::bind
, ou si votre compilateur prend en charge tr1/c++0x utilisationstd::tr1::function
etstd::tr1::bind
.Ainsi, il devient très simple:
Et votre jeu de rappel devient:
Sinon vous avez besoin pour mettre en œuvre certaines classe abstraite
Et ensuite utiliser:
Lors de votre classe sont modifiés dans:
Et bien sûr, si la fonction que vous voulez l'appeler ne change pas, vous pouvez juste mettre en œuvre une interface, c'est à dire tirer la Cible de certaines classe abstraite avec cet appel.
+1, boost::bind est certainement le chemin à parcourir pour C++-seulement de rappel
boost:bind est certainement la réponse est a la recherche d'. Je vais probablement avoir à installer boost.
quel compilateur utilisez-vous? Beaucoup ont déjà bind/les fonctions de la bibliothèque standard, donc pas besoin pour boost
Actuellement, je suis en utilisant gcc dans mon iMac, mais en fait j'ai de la création d'une bibliothèque qui doit compiler sous windows principalement.
OriginalL'auteur Artyom
Une astuce consiste à utiliser des interfaces au lieu de cela, de cette façon, vous n'avez pas besoin spécifiquement de connaître la classe dans votre "MyClassWithCallback', si l'objet passé en implémente l'interface.
par exemple (pseudo-code)
et
faire le rappel
réglage:
OriginalL'auteur Anders
La Observateur modèle de conception semble être ce que vous cherchez.
OriginalL'auteur Greg Sexton
Vous avez quelques options de base:
1) Préciser ce qui classe le rappel va utiliser, de sorte que le pointeur d'objet et une fonction membre types de pointeur sont connus, et peut être utilisé en l'appelant. La classe peut avoir plusieurs fonctions membres avec la même signature que vous pouvez choisir entre les deux, mais vos options sont assez limitées.
Une chose que vous avez fait de mal dans votre code, c'est que membre des pointeurs de fonction et gratuit des pointeurs de fonction en C++ ne sont pas les mêmes, et ne sont pas des types compatibles. Votre enregistrement de rappel fonction prend un pointeur de fonction, mais vous essayez de passer un pointeur de fonction membre. Pas autorisé. En outre, le type de "cet" objet fait partie de la catégorie de membre pointeur de fonction, donc il n'y a pas une telle chose en C++ comme "un pointeur vers n'importe quel membre de la fonction qui prend un entier et renvoie void". Il doit être, "un pointeur vers n'importe quel membre de la fonction de la Cible, qui prend un entier et renvoie void". D'où le nombre limité d'options.
2) Définir une fonction virtuelle pure dans une classe d'interface. Toute classe qui veut recevoir le rappel peut donc hériter de la classe d'interface. Grâce à l'héritage multiple, ce n'interfère pas avec le reste de votre hiérarchie de classe. C'est presque exactement la même que la définition d'une Interface en Java.
3) l'Utilisation d'un non-membre de la fonction pour la fonction de rappel. Pour chaque classe, qui veut l'utiliser, vous écrire un petit talon de gratuit fonction qui prend le pointeur d'objet et appelle le droit de la fonction membre. Donc dans votre cas, vous avez de l':
4) Utiliser des modèles:
Si vous pouvez utiliser des modèles dépend si votre ClassWithCallback fait partie de certaines grandes ancien cadre - si oui, alors il pourrait ne pas être possible (pour être précis: peut nécessiter quelques trucs de plus, tel qu'un modèle de classe qui hérite d'un non-modèle de la classe ayant une fonction membre virtuelle), parce que vous ne pouvez pas nécessairement instancier la totalité de la structure une fois pour chaque rappel destinataire.
OriginalL'auteur Steve Jessop
Aussi, regardez la Modèle Observateur et les signaux et les slots . Cela s'étend à plusieurs abonnés.
OriginalL'auteur StuartLC
En C++, des pointeurs vers des méthodes de la classe ne sont guère utilisées. Le fait que vous avez appelé en il est les délégués et leur utilisation n'est pas recommandée. Au lieu de cela, vous devez utiliser des fonctions virtuelles et classes abstraites.
Cependant, le C++ n'aurait pas été si friands de moi, si c'est pas pris en charge complètement différents concepts de la programmation. Si vous voulez toujours les délégués, vous devriez regarder dans la direction de "stimuler fonctionnelle" (une partie de C + +0 x), il permet des pointeurs vers des méthodes de classes quel que soit le nom de la classe. En outre, dans C++ Builder a type __fermeture - mise en œuvre d'un délégué au niveau du compilateur.
P. S. Désolé pour les mauvais en anglais...
OriginalL'auteur Daminian