2015-06-19 12 views
3

在我製作的遊戲中,會有觸發器。當觸發器與任何事物碰撞時,會發生某些事情;如果它是門觸發器,則玩家將移動到新的區域。如果它是爆炸觸發器,併發生爆炸。椅子扳機可能會讓玩家坐下。如何獲取一個通用函數指針作爲C++類的私有成員?

我不想爲每個觸發器都劃分子類。每個人都有足夠的重要信息,每個人都可以使用通用界面進行激活。它們之間的唯一區別是在碰撞時調用的例程。

問題是函數本身可能有不同的簽名。

例如,移動播放器功能需要一些東西。

void move_player(Environment *new_env, Player *player, int new_x, int new_y) 

但爆炸觸發可能只是

void explode() 

我需要一個接受move_playerexplode類。

這就是我認爲的僞代碼看起來應該像

class Trigger 
{ 
    public: 
     Trigger(function_pointer f) { fp = f; } 
     void activate() { fp(); } 

    private: 
     func_pointer fp; 
} 

我想初始化/使用它會是這個樣子。

auto f = std::bind(move_player, new_environment, my_player, 0, 0); 
Trigger tigger (f); 
tigger.activate(); 

我試過進入std文檔和搜索其他論壇,並檢查出Boost文檔。我知道如何使用綁定,我敢肯定它應該在這裏工作,但我沒有如何設置類中的函數指針對參數列表無動於衷。一個最小的工作例子會很棒。

+0

如果您不知道需要什麼參數,您將如何調用它? –

+0

你看過['std :: function'](http://en.cppreference.com/w/cpp/utility/functional/function)嗎? –

+0

根據你的描述,我最初的想法是,你應該建立一個虛擬的「觸發器」基類,然後研究多態技術來創建新的類,從Trigger繼承它們的屬性。 – tn3rt

回答

2

你可以結合使用std::functionstd::bind和可變參數模板如下面的例子:

class Trigger { 
    std::function<void()> fp; 
public: 
    template<typename F, typename ...Args> 
    Trigger(F f, Args... args) : fp(std::bind(f, args...)) { } 
    void activate() { fp(); } 
}; 

LIVE DEMO

2

你想在這裏使用的是std::function。更具體地說,一個std::function<void()>。也可以考慮使用一個lambda,而不是綁定的:

auto f = [=]() { movie_player(new_environment, my_player, 0, 0); }; 
2

雖然有可能這種使用std::functionstd::bind和/或lambda函數來解決,這只是編譯器和模板魔術創建自己的類 - 如果你是熱衷模板魔術,然後通過一切手段去爲它。但是我發現它並不能真正解決任何問題[需要解決],並且使代碼更難跟蹤和調試(因爲您遲早會想要調試移動播放器觸發器,很可能 - 至少除非您是比我更聰明的人,可以編寫永遠不需要調試的代碼)。在std::function::operator()中設置斷點很難正確,只有在需要時纔會中斷,而不是在從其他位置調用它時(例如,處理用戶輸入的std :: string小寫轉換函數)。 。

在這種情況下,我會說Trigger虛擬函數類是正確的。

MovePlayer [或者,如果你想將它命名move_player]類將或許是這樣的:

class MovePlayer : public Trigger 
{ 
    MovePlayer(Player *p, int x, int y) : player(p), dx, dy) {} 
    void Activate() override { player->SetPos(dx, dy); } 
private: 
    Player *player; 
    int dx, dy; 
}; 

[當然,你不應該使用原始指針 - 在這種情況下,使用std::shared_ptr<Player>和存儲std::weak_ptr<Player>MovePlayer]

+0

要點解釋和透視 – sehe

+0

我並不陌生與多態,但我想避免猖獗的子類化。你有調試的一點,但另一個人有我需要的解決方案。我想我需要擔心的下一件事是放置可能需要發送觸發器的函數的位置。感謝您向我展示弱和shared_ptrs。到目前爲止,我一直在使用普通的ol指針。 – DeepDeadpool

+0

我的觀點是「底層」,它仍然是子類[或類似的東西],只是它發生在你無法控制的一些模板代碼中 - 所以你只是保存一些輸入[也許]。 –