Maison  >  Article  >  développement back-end  >  Erreur de syntaxe C++ : le pointeur de fonction membre ne peut pas pointer vers une fonction non membre, comment y remédier ?

Erreur de syntaxe C++ : le pointeur de fonction membre ne peut pas pointer vers une fonction non membre, comment y remédier ?

王林
王林original
2023-08-22 16:43:471471parcourir

Erreur de syntaxe C++ : le pointeur de fonction membre ne peut pas pointer vers une fonction non membre, comment y remédier ?

En programmation C++, un pointeur de fonction membre est un pointeur vers une fonction membre d'une classe. L’utilisation de pointeurs de fonctions membres vous permet de sélectionner dynamiquement la fonction membre à appeler au moment de l’exécution, ce qui est une technique très utile. Cependant, nous rencontrons parfois un problème, c'est-à-dire que les pointeurs de fonctions membres ne peuvent pas pointer vers des fonctions non membres. Comment devons-nous gérer cela ?

Tout d'abord, vous devez comprendre pourquoi les pointeurs de fonctions membres ne peuvent pas pointer vers des fonctions non membres. En effet, les types de fonctions non membres sont différents de ceux des fonctions membres doivent implicitement transmettre ce pointeur pour accéder aux variables et fonctions membres de la classe. Par conséquent, le pointeur de fonction membre enregistre l'adresse de la fonction membre et le pointeur de classe, tandis que la fonction non membre n'a pas ce pointeur et ne peut pas accéder aux variables membres et aux fonctions de la classe, de sorte que le pointeur de fonction membre ne peut pas pointer vers un fonction non-membre.

Nous pouvons résoudre ce problème avec quelques astuces. Voici quelques solutions :

  1. Utilisez des foncteurs ou des expressions lambda

Un foncteur est une classe qui implémente un opérateur d'appel de fonction. Nous pouvons surcharger l'opérateur d'appel de fonction afin que les objets d'une classe puissent être appelés comme des fonctions. Par conséquent, nous pouvons utiliser un foncteur pour implémenter la fonction d'une fonction membre, afin que le pointeur de la fonction membre puisse pointer vers l'objet foncteur. Les expressions Lambda peuvent également atteindre la même fonctionnalité.

Ce qui suit est un exemple d'utilisation d'un foncteur :

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

class FunctionObject {
public:
    void operator()() {
        obj.foo();
    }
    MyClass obj;
};

int main() {
    FunctionObject f;
    f();
    return 0;
}

Dans le code ci-dessus, nous définissons une classe FunctionObject, qui contient un objet MyClass et une fonction Operator(). Lorsque l'objet foncteur est appelé, il sera appelé opérateur. (), appelant ainsi la fonction foo de MyClass.

Nous pouvons appeler la fonction foo en passant l'adresse de l'objet FunctionObject au pointeur de fonction membre. Par exemple :

void (MyClass::*func_ptr)() = &MyClass::foo;
FunctionObject f;
MyClass* p = &(f.obj);
(p->*func_ptr)();

Dans le code ci-dessus, nous définissons un pointeur de fonction membre func_ptr, pointant vers la fonction foo de MyClass. Ensuite, nous avons créé un objet FunctionObject f et attribué l'adresse de son membre obj au pointeur MyClass p. Enfin, nous appelons la fonction foo en utilisant l'opérateur d'accès aux membres (p->*) et le pointeur de fonction membre func_ptr.

  1. Utilisez des fonctions globales et des pointeurs void*

Une autre solution consiste à utiliser des fonctions globales et des pointeurs void*. Nous pouvons définir une fonction globale qui accepte un pointeur void comme paramètre et le convertit en pointeur vers la classe et appelle la fonction membre. Ensuite, nous pouvons attribuer l'adresse de cette fonction globale au pointeur de fonction membre pour appeler la fonction membre de la classe.

Ce qui suit est un exemple d'utilisation d'une fonction globale et d'un pointeur void* :

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

void invoke_function(void* obj_ptr, void (*func_ptr)()) {
    MyClass* p = static_cast<MyClass*>(obj_ptr);
    (p->*func_ptr)();
}

int main() {
    void (*func_ptr)() = &MyClass::foo;
    MyClass obj;
    invoke_function(&obj, func_ptr);
    return 0;
}

Dans le code ci-dessus, nous définissons une fonction globale Invocation_function, qui accepte un pointeur void

et un pointeur de fonction comme paramètres. Dans la fonction Invocation_function, nous convertissons le pointeur void obj_ptr en pointeur MyClass p, et utilisons l'opérateur d'accès aux membres (p->*) et le pointeur de fonction func_ptr pour appeler la fonction foo. Dans la fonction principale, nous définissons un pointeur de fonction membre func_ptr, pointant vers la fonction foo de MyClass. Ensuite, nous créons un objet MyClass obj et transmettons son adresse à la fonction Invoquer_fonction, puis passons func_ptr à la fonction Invoquer_fonction.

Résumé

Le pointeur de fonction membre est un outil puissant qui nous permet de sélectionner dynamiquement la fonction membre à appeler au moment de l'exécution. Cependant, lorsque nous utilisons des pointeurs de fonctions membres, si nous devons pointer vers des fonctions non membres, nous pouvons utiliser des foncteurs ou des expressions Lambda, ou utiliser des fonctions globales et des pointeurs void*. Ces techniques peuvent nous aider à résoudre le problème selon lequel les pointeurs de fonctions membres ne peuvent pas pointer vers des fonctions non membres.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn