1

J'ai un problème particulier que je veux résoudre, je ne suis pas sûr que ce soit possible car je ne trouve aucune information ou exemple de ce fait . Fondamentalement, je:Pointeur vers la fonction membre de la classe dérivée, mais pas de fonction dérivée (virtuelle)

class ParentObject {}; 

class DerivedObject : public ParentObject 
{ 
    void myFunction(){} 
}; 

class OtherDerivedObject 
{ 
    void myOtherFunction(){} 
}; 

et que vous voulez un pointeur de fonction ParentObjet :: * et avoir en mesure de prendre des fonctions soit de classe dérivée. Ma raison de vouloir le faire, j'ai une autre classe

class functionRegistry 
{ 
    std::map<string, *functionPoint> functionMap; 
} 

et chaque objet (idéalement dans ParentObjet mais peut faire individuellement dans les objets dérivés si nécessaire) ont une instance d'un functionRegistry, et je dois functionPoint à être capable de pointer vers des fonctions dans des objets de type DerivedObject ou OtherDerivedObject.

Merci à l'avance

+3

On dirait [un problème XY classique] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) pour moi. – YSC

+0

pourriez-vous élaborer plus en particulier quel est votre cas d'utilisation? –

+0

Ok, j'ai une solution maintenant (ci-dessous) mais pour le bien de l'intérêt: J'écris un moteur de jeu en utilisant l'architecture basée sur l'entité de composant, où les composants se parlent par des messages simples. Les messages se composent de choses comme FORCE_X + 50, où je vais analyser le message en: la première moitié qui sera corrélée à une fonction et la seconde qui sera un argument .. Je pense que cela crée un environnement flexible pour moi d'ajouter facilement fonctionnalité où j'en ai besoin.Différents composants prendront différents messages et feront des choses différentes. – ChrysmPsy

Répondre

2

Tout ce que vous avez besoin est un static_cast pour remplir la carte avec le bon type.

using pfunc_type = void (ParentObject::*)() ; 
pfunc_type pfunc1 = static_cast<pfunc_type>(&DerivedObject::myFunction); 

Comme cela est permis par la norme:

[expr.static.cast/12] - §5.2.9¶12

A prvalue de type « pointeur vers un membre de D Type de cv1 T "peut être converti en une prvalue de type" pointeur vers le membre de B de type cv2 T ", où B est une classe de base (Clause [class.derived]) de D, si cv2 est le même cv- qualification comme, ou gr mangeur cv-qualification que, cv1.72 Si aucune conversion standard valide de "pointeur à membre de B de type T" à "pointeur à membre de D de type T" existe ([conv.mem]), le programme est mal formé. La valeur de pointeur de membre null ([conv.mem]) est convertie à la valeur de pointeur de membre null du type de destination. Si la classe B contient le membre d'origine ou est une classe de base ou dérivée de la classe contenant le membre d'origine, le pointeur vers le membre pointe vers le membre d'origine. Sinon, le comportement n'est pas défini. [ Remarque: bien que la classe B ne contienne pas nécessairement le membre d'origine, le type dynamique de l'objet avec lequel l'indirection passe par le pointeur vers le membre doit contenir le membre d'origine; voir [expr.mptr.oper]. - Note de fin]

Mais tout cela est permis, vous devez être très soin de vous assurer que vous appliquez le pointeur à l'élément sur un objet du type dynamique correcte.

+0

Excellent, cela semble avoir fait l'affaire, merci! – ChrysmPsy

+0

Pourquoi le comportement est indéfini? Pourquoi cela ne peut pas être une erreur de compilation? – Mikhail

+0

@Mikhail - Supposons une fonction qui accepte un pointeur, une fonction membre d'une classe de base et un pointeur vers un objet de classe de base. Comment vérifieriez-vous au moment de la compilation cette contrainte? – StoryTeller