2010-10-31 5 views
0

Je tente de comparer l'adresse de deux fonctions pour l'égalité. Le type de ma fonction stockée est connu. Ce système fonctionne normalement, considérez le code suivant (écrit échantillon non du programme):Conversion du pointeur de fonction de classe en void * ou vice versa

virtual bool compare(void *fn2) { 
    void (*fn)(int); 

    if(fn==fn2) 
    return true; 
} 

Toutefois, lorsque les fonctions de classe sont entrées en considération la même méthode ne fonctionne pas.

virtual bool compare(void *fn2) { 
    void(__thiscall myclass::*fn)(int); 
    void *fn2; 

    if(fn==fn2) //error C2440 type cast: cannot convert void* to void(__thiscall... 
    return true; 
} 

Ces fonctions remplacent une fonction virtuelle pure de classe de base commune similaire à ce qui suit:

virtual bool compare(void*) = 0; 

Puisque je ne peux pas utiliser le modèle <> dans des fonctions virtuelles, je suis d'options. Existe-t-il un moyen (de toute façon) d'unifier les fonctions de classe et les fonctions régulières?

Merci à l'avance, Cem

+0

Vous ne pouvez pas convertir des pointeurs de fonction ou des pointeurs de fonction membres en pointeurs vides ("pointeurs vers des objets") sans réinterprétation définie par l'implémentation, ce qui signifie que nous avons besoin de beaucoup plus de détails. –

+1

La question qui vient à l'esprit est de savoir quel est le véritable cas d'utilisation qui motive cette nécessité. Je peux imaginer qu'il pourrait y avoir différentes conceptions pour résoudre le même problème qui peut réellement être implémenté dans la langue. –

+2

@David: En d'autres termes, il pose des questions sur la tentative de solution [plutôt que le problème] (http://tinyurl.com/meta-xy). –

Répondre

5

Posix nécessite la capacité de convertir des pointeurs de fonction pour void*. La norme C++ ne le supporte pas.

Les pointeurs de fonction de membre ne sont pas des pointeurs au sens ordinaire, ils ressemblent plus à des décalages (même pour une fonction de membre non virtuelle). Les deux implémentations que vous affichez pour compare ont un comportement indéfini même si les comparaisons et les conversions sont valides, car elles ne retournent rien dans le cas où les pointeurs ne sont pas égaux. Au lieu de if(blah == bag){ return true; } faites simplement return (blah == bah);.

Les problèmes découlent de l'élimination des informations de type nécessaires. Ce n'est généralement pas une bonne idée. Pourquoi rejettez-vous les informations de type dont vous avez besoin?

Solution: (1) ne jetez pas les informations de type nécessaires, et (2) refonte pour se débarasser de cette fonction compare. Prenez également note du commentaire de Roger Pate selon lequel il semble que vous vous interrogiez sur une tentative de solution particulière plutôt que sur le problème. Quel est le problème?

Vive & HTH.,

+0

Sry, j'étais un peu vague, mon but est d'écrire un système d'événement bouillonnant. Il fonctionne déjà et est utilisé, mais pour supprimer des fonctions de la liste, je renvoie des index et en utilisant ces index, on peut supprimer une fonction de la liste. Cependant, je souhaite ajouter une capacité à supprimer une fonction en la réapprovisionnant. Si les fonctions membres sont stockées comme des décalages, il n'y a aucun moyen de les identifier de façon unique (ai-je tort?), Il n'y a donc aucun moyen d'implémenter cette fonctionnalité. –

+3

@Cem: Si vous essayez d'identifier par le seul pointeur de fonction, alors ce n'est pas unique. Mais généralement, vous auriez également stocké l'objet sur lequel la fonction sera appelée, et ensemble, il serait unique. Cependant, une meilleure approche consisterait à envelopper la fonction cible et membre dans un objet functor. Vous pouvez définir une interface avec des fonctions virtuelles pures pour l'invocation (c'est-à-dire 'operator()' et comparaison), puis utiliser une classe modèle pour les instances concrètes. C'est la façon standard de résoudre ceci en C++. –

+0

Je pense que je vais créer une fonction qui va essayer de convertir la classe de base à la sous-classe Je veux utiliser dynamic_cast, si la conversion est NULL comparer est échoué, sinon elle utilisera la fonction de comparaison non commune en utilisant compare (void (__ thiscall myclass :: * fn) (int)) {...} fonction qui peut 1-1 les comparer. Btw compare fonction sait quelle classe à exploiter et comparer (en fait, il a deux arguments). –

2

Cela ne fonctionne pas parce que les pointeurs de fonctions membres ne sont pas réellement convertibles en pointers- régulière leur taille est définie. Dans certaines implémentations de certaines hiérarchies de classes, le pointeur de fonction membre peut avoir cinq fois la taille d'un pointeur normal. Comment cela va-t-il fonctionner avec une comparaison avec void *?

Questions connexes