C++ Member Function Pointers

折月煮酒 提交于 2019-12-06 04:23:14

I think that the line you're looking for is

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

Let's dissect this. First, we need to get to the actual member function pointer, which is

spawn->ptr

Since, here, spawn is a pointer, and we have to use -> to select the ptr field.

Once we have that, we need to use the pointer-to-member-selection operator to tell ent to select the appropriate member function:

ent->*(spawn->ptr)

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

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

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 say

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

Hope this helps!

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!)

class EntitySpawn 
{
public:
    void spawn_entity()
    {
        spawn();
    }

private:
    // std::string 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);
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!