Il n'y a rien de mal à utiliser des pointeurs de fonction. Cependant, les pointeurs vers des fonctions membres non statiques ne sont pas comme les pointeurs de fonction normaux: les fonctions membres doivent être appelées sur un objet qui est passé comme argument implicite à la fonction. La signature de votre fonction membre ci-dessus est donc
void (aClass::*)(int, int)
plutôt que le type que vous essayez d'utiliser
void (*)(int, int)
Une approche pourrait consister à faire fonctionner le membre, static
auquel cas il ne nécessite aucun objet pour être appelé et vous pouvez l'utiliser avec le type void (*)(int, int)
.
Si vous avez besoin d'accéder à un membre non statique de votre classe et que vous devez vous en tenir aux pointeurs de fonction, par exemple, parce que la fonction fait partie d'une interface C, votre meilleure option est de toujours passer un void*
à votre fonction en prenant des pointeurs de fonction et d'appeler votre membre via une fonction de transfert qui obtient un objet de la void*
puis appelle la fonction membre.
Dans une interface C ++ appropriée, vous voudrez peut-être jeter un œil à la manière dont votre fonction prend un argument basé sur un modèle pour que les objets fonction utilisent des types de classe arbitraires. Si l'utilisation d'une interface basée sur un modèle n'est pas souhaitable, vous devez utiliser quelque chose comme std::function<void(int, int)>
: vous pouvez créer un objet fonction convenablement appelable pour ceux-ci, par exemple en utilisant std::bind()
.
Les approches de type sécurisé utilisant un argument de modèle pour le type de classe ou un type approprié std::function<...>
sont préférables à l'utilisation d'une void*
interface car elles suppriment le potentiel d'erreurs dues à une conversion vers le type incorrect.
Pour clarifier comment utiliser un pointeur de fonction pour appeler une fonction membre, voici un exemple:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}