首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++成员函数指针

C++成员函数指针
EN

Stack Overflow用户
提问于 2012-02-08 14:01:34
回答 2查看 1.1K关注 0票数 3

我正在用C++做一个小游戏,我发现了类成员的函数指针。我没有任何想法让它们以正确的方式工作,但这里是我的尝试。

代码语言:javascript
复制
// 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();

    [...]
}

你能给我一个好的建议来正确地实现它们吗?

诚挚的问候。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-08 14:07:13

我想你要找的那条线是

代码语言:javascript
复制
(ent->*(spawn->ptr))();

让我们仔细分析一下。首先,我们需要找到实际的成员函数指针,即

代码语言:javascript
复制
spawn->ptr

因为在这里,spawn是一个指针,我们必须使用->来选择ptr字段。

完成后,我们需要使用指向成员选择的指针操作符来告诉ent选择适当的成员函数:

代码语言:javascript
复制
ent->*(spawn->ptr)

最后,为了调用函数,我们需要告诉C++调用这个成员函数。由于C++中的运算符优先级问题,您首先必须将计算结果为成员函数的整个表达式放在圆括号中,因此我们有

代码语言:javascript
复制
(ent->*(spawn->ptr))();

无论如何,这是我在一段时间内看到的最奇怪的C++代码行之一。:-)

在一个完全不相关的问题上,因为您使用的是C++,所以我会避免使用typedef struct。就说

代码语言:javascript
复制
struct t_dEntitySpawn {
  std::string name;
  void (dEntity::*ptr)();
};

希望这能有所帮助!

票数 5
EN

Stack Overflow用户

发布于 2012-02-08 14:10:41

在这种情况下,正确的编程方法是停止像C++中的C那样的编程,开始使用诸如虚函数之类的C++特性。:-P

我之所以说“像C一样编程”,是因为您所做的类似于C程序员在C语言中实现polymorphism的方式。在C++中不需要这样做,因为C++附带了对多态性的内置支持,该支持旨在帮助解决您的情况。虚函数是C++实现多态性的方式。

更不用说在这种情况下,通过函数指针的多态性可能比您现在拥有的要快得多,因为C++虚函数不需要字符串比较就能工作。

成员函数指针有一些用例。这种情况不在其中。尤其是因为它模糊了你代码的意图。(请记住,代码是供人类阅读的!)

代码语言:javascript
复制
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);
};
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9188521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档