C ++:如何构建没有void指针的事件/消息系统? [英] C++: How to build an events / messaging system without void pointers?

查看:140
本文介绍了C ++:如何构建没有void指针的事件/消息系统?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的C ++项目中有一个动态消息系统,其中有一个固定的现有事件列表,事件可以在运行时任何地方触发,以及可以在某些事件中订阅回调函数。 p>

在这些事件中传递的参数应该有一个选项。例如,一个事件可能不需要任何参数(EVENT_EXIT),有些可能需要多个(EVENT_PLAYER_CHAT:Player对象指针,带消息的String)



第一个可能的选项是允许在触发事件时将一个void指针作为参数传递给事件管理器,并接收它在回调函数中。



虽然:我被告知void指针是不安全的,我不应该使用它们。




  • 如何在不使用void指针的情况下保留(半)动态参数类型和计数值?


解决方案

您可以使用基类,可选地抽象,并使用 dynamic_cast 。参数将在运行时检查。不过,编译时可能会更好。

  class EventArgs 
{
public:
virtual〜EventArgs();
};

class PlayerChatEventArgs:public EventArgs
{
public:
PlayerChatEventArgs(Player * player,const std :: string& message);
virtual〜PlayerChatEventArgs();
Player * GetPlayer()const;
const std :: string& GetMessage()const;
私人:
玩家*玩家;
std :: string message;
};

class Event
{
public:
virtual〜Event()= 0;
virtual void Handle(const EventArgs& args)= 0;
};

class ExitEvent:public Event
{
public:
virtual〜ExitEvent();
virtual void Handle(const EventArgs& / * args * /)
{
//执行退出的东西。
}
};

class PlayerChatEvent:public Event
{
public:
virtual〜PlayerChatEvent();
virtual void Handle(const EventArgs& args)
{
//如果投射失败,这将抛出一个bad_cast异常。
const PlayerChatEventArgs& playerchatargs =
dynamic_cast< const PlayerChatEventArgs&>(args);
//执行玩家聊天的东西。
}
};


I'd like to have a dynamic messaging system in my C++ project, one where there is a fixed list of existing events, events can be triggered anywhere during runtime, and where you can subscribe callback functions to certain events.

There should be an option for arguments passed around in those events. For example, one event might not need any arguments (EVENT_EXIT), and some may need multiple ones (EVENT_PLAYER_CHAT: Player object pointer, String with message)

The first option for making this possible is allowing to pass a void pointer as argument to the event manager when triggering an event, and receiving it in the callback function.

Although: I was told that void pointers are unsafe and I shouldn't use them.

  • How can I keep (semi) dynamic argument types and counts for my events whilst not using void pointers?

解决方案

You could use a base class, optionally abstract, and use dynamic_cast. The argument will be checked at run-time. A compile-time would probably be better, though.

class EventArgs
{
public:
   virtual ~EventArgs();
};

class PlayerChatEventArgs : public EventArgs
{
public:
   PlayerChatEventArgs(Player* player, const std::string& message);
   virtual ~PlayerChatEventArgs();
   Player* GetPlayer() const;
   const std::string& GetMessage() const;
private:
   Player* player;
   std::string message;
};

class Event
{
public:
   virtual ~Event() = 0;
   virtual void Handle(const EventArgs& args) = 0;
};

class ExitEvent : public Event
{
public:
   virtual ~ExitEvent();
   virtual void Handle(const EventArgs& /*args*/)
   {
      // Perform exit stuff.
   }
};

class PlayerChatEvent : public Event
{
public:
   virtual ~PlayerChatEvent();
   virtual void Handle(const EventArgs& args)
   {
      // this will throw a bad_cast exception if cast fails.
      const PlayerChatEventArgs& playerchatargs =
         dynamic_cast<const PlayerChatEventArgs&>(args);
      // Perform player chat stuff.
   }
};

这篇关于C ++:如何构建没有void指针的事件/消息系统?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆