Indicateurs de fonction de membre C ++

Je fais un petit jeu en C ++ et je découvre les indicateurs de fonction des membres de la classe. Je n’ai aucune idée de les faire fonctionner correctement, mais voici ma tentative.

// A struct where the function pointer will be stored for the call // By the way, is there a way to do the same thing with classes ? // or are structs still fine in C++ ? (Feels like using char instead of ssortingng) typedef struct s_dEntitySpawn { std::ssortingng name; void (dEntity::*ptr)(); } t_dEntitySpawn; // Filling the struct, if the entity's classname is "actor_basicnpc", // then I would like to do a call like ent->spawnBasicNPC t_dEntitySpawn dEntitySpawns[] = { { "actor_basicnpc", &dEntity::spawnBasicNPC }, { 0, 0 } }; // This is where each entity is analyzed // and where I call the function pointer void dEntitiesManager::spawnEntities() { dEntity *ent; t_dEntitySpawn *spawn; [...] // It makes an error here, feels very weird for me if (!spawn->name.compare(ent->getClassname())) ent->*spawn.ptr(); [...] } 

Pourriez-vous s’il vous plaît me donner un bon conseil sur la bonne façon de les mettre en œuvre?

Meilleures salutations.

Je pense que la ligne que vous cherchez est

 (ent->*(spawn->ptr))(); 

Disséquons ceci. Tout d’abord, nous devons accéder au pointeur de la fonction membre actuelle, qui est

 spawn->ptr 

Depuis, spawn est un pointeur et nous devons utiliser -> pour sélectionner le champ ptr .

Une fois que nous avons cela, nous devons utiliser l’opérateur de sélection pointeur-membre-membre pour indiquer à l’ ent de sélectionner la fonction membre appropriée:

 ent->*(spawn->ptr) 

Enfin, pour appeler la fonction, nous devons dire à C ++ d’appeler cette fonction membre. En raison de problèmes de priorité des opérateurs en C ++, vous devez d’abord mettre entre parenthèses l’expression entière évaluée comme fonction membre. Nous devons donc:

 (ent->*(spawn->ptr))(); 

Pour ce que ça vaut, c’est l’une des lignes de code C ++ les plus étranges que j’ai vues depuis un moment. 🙂

Sur une note totalement indépendante, étant donné que vous utilisez C ++, typedef struct utilisation de typedef struct . Dis le

 struct t_dEntitySpawn { std::ssortingng name; void (dEntity::*ptr)(); }; 

J’espère que cela t’aides!

La bonne façon de programmer dans ce cas est d’arrêter de programmer comme C en C ++ et de commencer à utiliser les fonctionnalités C ++ comme les fonctions virtuelles. 😛

Je dis “programmation comme C” car ce que vous faites ressemble à la façon dont les programmeurs C implémentent le polymorphism dans le langage C. Inutile de faire cela en C ++, car celui-ci est livré avec une prise en charge intégrée du polymorphism, conçue pour vous aider à résoudre votre problème. Les fonctions virtuelles sont la façon dont C ++ implémente le polymorphism.

Sans oublier que dans ce cas, le polymorphism via les pointeurs de fonction peut être beaucoup plus rapide que ce que vous avez maintenant car la comparaison de chaînes n’est pas nécessaire pour que les fonctions virtuelles C ++ fonctionnent.

Il existe des cas d’utilisation pour les pointeurs de fonction membre. Cette situation n’en fait pas partie. Surtout que cela masque l’intention de votre code. (Rappelez-vous, le code est là pour que les humains lisent!)

 class EntitySpawn { public: void spawn_entity() { spawn(); } private: // std::ssortingng name; // Not necessary for polymorphism to work virtual void spawn() = 0; }; class ActorBasicNPC : public EntitySpawn { private: virtual void spawn() { /* implementation specific to ActorBasicNPC */ } }; void test_spawn(EntitySpawn& es) { // This will call the correct implementation of spawn(), // even though we only got a reference to an EntitySpawn. es.spawn_entity(); } int main() { ActorBasicNPC npc; // Calls ActorBasicNPC::spawn() even though only a // reference to EntitySpawn was passed. test_spawn(npc); };