簡體   English   中英

將虛擬函數放入結構中

[英]Putting virtual functions inside a struct

我的目標是編寫一個用於處理游戲事件的系統,該系統可以由某種事件的發生觸發,例如玩家走路殺死某物或拿走一件物品或您擁有的物品。 為此,我需要有一個虛擬函數在事件觸發時執行。 這是我想做的事情的要點(我知道它在當前狀態下不起作用,但這是我可以解釋我的目標的最佳方法):

class EventManager
{
    public:
        typedef struct
        {
            virtual void run();
            bool triggered;
            std::string name;
        } Event;

        void newEvent(std::string eventName)
        {
            Event newEvent;
            newEvent.name = eventName;
            newEvent.triggered = false;
            eventStack.push_back(newEvent);
        }

        void triggerEvent(std::string eventName)
        {
            std::vector<Event>::iterator itr;

            for(itr = eventStack.begin(); itr != eventStack.end(); itr++)
            {
                if(itr->name == eventName) itr->triggered = true;
            }
        }

        std::vector<Event> eventStack;
};

int main()
{
    EventManager* myEventManager = 0;
    myEventManager = new EventManager();

    myEventManager->newEvent("Event1");
    myEventManager->eventStack.back()::run()
    {
        std::cout << "Event1 has been triggered";
    }

    std::vector<EventManager::Event>::iterator itr;

    for(itr = myEventManager->eventStack.begin(); itr != myEventManager->eventStack.end(); itr++)
    {
        if(itr->triggered)
        {
            itr->run();
            itr->triggered = false;
        }
    }

    return 0;
}

因此,基本上我的問題是,如何允許我的庫用戶定義事件觸發時發生的情況,而不必讓他們為每個事件編寫類或其他內容?

考慮一下: 什么是真正的事件? 一個事件(從其實現的角度來看)只是一個處理程序(回調)列表。

您所謂的Event實際上是代表事件處理程序的類,而EventManager是事件本身。

解決問題的方法非常簡單:使用函數引用(函數指針,lambda,函子)存儲處理程序集。 例如:

template<typename... ARGS>
struct event
{
   typedef void(*)(ARGS...) handler_type;


   void add_handler(handler_type handler)
   {
        handlers.push_back(handler);
   }

   void raise_event(ARGS args...)
   {
        for(handler_type handler : handlers)
            handler(args...);
   }

private:
    std::vector<handler_type> handlers;
};


void on_foo(int a,int b) { std::cout << "on foo!!! (" << a << "," << b << ")" << std::end; }


int main()
{
    event<int,int> foo;

    foo.add_handler(on_foo);

    foo.raise_event(0,0);
}

上面的實現可以使用完美的轉發進行優化,但我不想使示例過於復雜。

暫無
暫無

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

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