Question

Je veux déclarer la définition de type pour une signature de fonction membre. fonction Global typedefs ressemblent à ceci:

typedef int (function_signature)(int, int);
typedef int (*function_pointer) (int, int);

Mais je ne peux pas la même chose pour une fonction membre:

typedef int (foo::memberf_signature)(int, int);   // memberf_pointer is not a member of foo
typedef int (foo::*memberf_pointer)(int, int);

Il semble logique pour moi, parce que « foo :: » ist la syntaxe d'accéder à un membre de la classe foo. Comment puis-je typedef simplement la signature?

Était-ce utile?

La solution

Pour toute question concernant la syntaxe du pointeur de fonction maladroit, j'utilise personnellement un cheat-sheet: La fonction Pointeurs Tutorial ( téléchargeable ici , grâce à vecteur pour pointer dehors).

La signature d'une fonction de membre, cependant, est un peu différent de la signature d'une fonction régulière, que vous avez vécu.

Comme vous le savez probablement, une fonction membre a un paramètre caché, this, dont le type doivent être indiquées.

// C++11 and above.
using Member = int (Foo::*)(int, int);

// C++03 and below.
typedef int (Foo::*Member)(int, int);

ne vous permet de spécifier que le premier élément passé à la fonction sera Foo* (et donc votre méthode prend vraiment 3 arguments, quand vous pensez, pas seulement 2.

Cependant, il y a une autre raison aussi, pour vous forcer à préciser le type.

Un pointeur de fonction peut faire référence à une fonction virtuelle, où les choses de cas peut être assez compliqué. Par conséquent, la très Taille de la représentation en mémoire varie en fonction du type de fonction. En effet, sur Visual Studio, la taille d'un pointeur de fonction peut varier entre 1 et 4 fois la taille d'un pointeur régulier. Cela dépend si la fonction est virtuelle, notamment.

Par conséquent, la classe la fonction se réfère à fait partie de la signature , et il n'y a pas de travail autour.

Autres conseils

Vous pouvez factoriser la classe cible en C ++ moderne (post 11) en utilisant le modèle qualités "de typedefing alias . Ce que vous devez ressemblerait à:

template<typename T>
using memberf_pointer = int (T::*)(int, int); 

Pourtant, au moment de la déclaration, un pointeur vers une fonction membre en utilisant cette syntaxe aurait besoin de spécifier la classe cible:

// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D; 

Il fonctionne pour moi:

#include <iostream>

class foo
  {
public:
  int g (int x, int y) { return x + y ; }
  } ;

typedef int (foo::*memberf_pointer)(int, int);

int main()
  {
  foo f ;
  memberf_pointer mp = &foo::g ;
  std::cout << (f.*mp) (5, 8) << std::endl ;
  }

La raison pour laquelle il ne fonctionne pas avec votre syntaxe actuelle est que dicte la priorité des opérateurs que vous faites référence à une fonction nommée foo::memberf_signature, aucune sorte de type.

Je ne sais pas avec certitude si vous pouvez le faire ou non, mais je ne pouvais pas venir avec une combinaison de parenthese qui a induit le code à compiler avec g ++ 4.2.

Eh bien en fait, il ne peut pas travailler (je sais au moins aucun moyen en utilisant g ++); Utilisation de Borland compilateur c ++ il y aurait le mot-clé __closure.

La raison pour laquelle il n'est pas décompiler, que sizeof le functionpointer (sur une machine x86) occupe toujours << 32bits >>; mais si vous voulez pointer vers une signature classe (interface), le sizeof doit être 64bit: 32 bits pour le ce pointeur (comme l'interface de classe est dans la mémoire une seule fois) et 32 ??bits pour la fonction réelle

Mais le mot-clé __closure est un 'hack' langage BCB pas standardisé ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top