I'm doing a little game in C++ and I'm discovering the class members function pointers. I don't have any idea to make them work in the right way, but here is my attempt.
// 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 string)
typedef struct s_dEntitySpawn
{
std::string 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();
[...]
}
Could you please give me a good advice about the right way to implement them ?
Best regards.
The right way to program in this case is to stop programming like C in C++ and start using C++ features like virtual functions. :-P
I say "programming like C" because what you're doing resembles how C programmers implement polymorphism in the C language. There's no need to do that in C++ because C++ comes with built-in support for polymorphism, which was designed to help solve your situation. Virtual functions are how C++ implements polymorphism.
Not to mention that in this case, polymorphism via function pointers can be much faster than what you have now since string comparison is not required for C++ virtual functions to work.
There are use cases for member function pointers. This situation is not one of them. Especially since it obscures the intent of your code. (Remember, code is there for humans to read!)
I think that the line you're looking for is
Let's dissect this. First, we need to get to the actual member function pointer, which is
Since, here,
spawn
is a pointer, and we have to use->
to select theptr
field.Once we have that, we need to use the pointer-to-member-selection operator to tell
ent
to select the appropriate member function:Finally, to call the function, we need to tell C++ to invoke this member function. Due to operator precedence issues in C++, you first have to parenthesize the entire expression that evaluates to the member function, so we have
For what it's worth, this is one of the weirdest lines of C++ code that I've seen in a while. :-)
On a totally unrelated note, because you're using C++, I would avoid using
typedef struct
. Just sayHope this helps!