7 votes

Création d'une variable de fonction pointeur de membre de classe qui pointe vers une fonction membre de classe non statique

L'objectif est de faire en sorte que la variable membre _AddValue point sur le CreateFirstValue lors de l'initialisation de la classe et après la première invocation de la fonction AddValue tous les futurs appels à cette fonction invoqueront CreateAnotherValue .

Auparavant, je n'avais qu'un seul AddValue avec un contrôle conditionnel pour déterminer la fonction à appeler. Cependant, j'ai l'impression que cette implémentation est défectueuse parce que la fonction if se produira à chaque fois et il semble qu'un pointeur de fonction serait utile ici.

Un exemple :

class Foo
{
 private:
  int _value;
  void (*_AddValue)(int value); // Pointer to function member variable

  void CreateFirstValue(int value)
  {
    _value = value;
    _AddValue = &CreateAnotherValue;
  }

  void CreateAnotherValue(int value)
  {
    // This function will create values differently.
    _value = ...;
  }

 public:
  // Constructor
  Foo()
   : _value(0), _AddValue(CreateFirstValue)
  {
  }

  AddValue(int value) // This function is called by the user.
  {
    _AddValue(value);
  }
};

Le code ci-dessus n'est pas le code réel, juste un exemple de ce que j'essaie d'accomplir.

En ce moment, j'obtiens une erreur : argument of type void (BTree::)(int) does not match void (*)(int)

15voto

Ben Voigt Points 151460
&CreateAnotherValue

Cette syntaxe n'est pas valide. Pour créer un pointeur sur un membre, vous devez nommer la classe, même à l'intérieur des autres membres. Essayez

&Foo::CreateAnotherValue

Dans ce cas, vous parlez de l'adresse d'une qualifié fonction membre non statique, ce qui est autorisé et évite l'erreur concernant l'adresse de l'utilisateur. sans qualification fonction membre.

Bien sûr, vous avez besoin d'une variable correctement typée pour stocker le pointeur vers le membre, voir la réponse de Bo pour la déclaration correcte. Lorsque le moment est venu de l'appeler, vous devrez utiliser l'opérateur de déréférencement de pointeur-à-membre (soit .* o ->* ), alors disons

(this->*_AddValue)(whatever);

La même règle s'applique aux données, si vous dites &Foo::_value vous obtenez un pointeur sur un membre de type int Foo::* . Mais dans le cas des données, le nom non qualifié est également accepté, mais avec un comportement très différent. &_value donne un pointeur normal, le type int* qui est l'adresse de l'unité spécifique _value à l'intérieur de la variable membre this instance.

7voto

Bo Persson Points 42821

  void (*_AddValue)(int value) ; // Pointeur vers la variable membre de la fonction

Il ne s'agit pas vraiment d'un pointeur vers un membre, mais d'un pointeur vers une fonction libre.

Tu dois faire ça

void (Foo::*_AddValue)(int value); // Pointer to function member variable

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X