簡體   English   中英

C ++成員函數指針

[英]C++ Member Function Pointers

我正在用C ++做一個小游戲,我發現了類成員函數指針。 我不知道讓它們以正確的方式工作,但這是我的嘗試。

// 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();

    [...]
}

你能否就正確實施方法給我一個很好的建議?

最好的祝福。

我認為你正在尋找的那條線是

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

讓我們剖析一下。 首先,我們需要獲取實際的成員函數指針,即

spawn->ptr

因為,這里, spawn是一個指針,我們必須使用->來選擇ptr字段。

一旦我們有了這個,我們需要使用指向成員選擇的指針運算符來告訴ent選擇適當的成員函數:

ent->*(spawn->ptr)

最后,要調用該函數,我們需要告訴C ++調用這個成員函數。 由於C ++中的運算符優先級問題,您首先必須將整數表達式括起來,該表達式求值為成員函數,因此我們有

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

對於它的價值,這是我在一段時間內看到的最奇怪的C ++代碼行之一。 :-)

在一個完全不相關的說明中,因為你正在使用C ++,我會避免使用typedef struct 說啊

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

希望這可以幫助!

在這種情況下編程的正確方法是在C ++中停止像C一樣的編程,並開始使用像虛擬函數這樣的C ++特性。 :-P

我說“像C一樣編程”,因為你所做的就像C程序員在C語言中實現多態的方式。 在C ++中沒有必要這樣做,因為C ++帶有內置的多態性支持,旨在幫助解決您的問題。 虛函數是C ++實現多態的方式。

更不用說在這種情況下,通過函數指針的多態性可以比現在快得多,因為C ++虛函數不需要進行字符串比較。

成員函數指針有用例。 這種情況不是其中之一。 特別是因為它模糊了代碼的意圖。 (請記住,代碼可供人類閱讀!)

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);
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM