21xrx.com
2024-12-26 16:03:52 Thursday
登录
文章检索 我的文章 写文章
C++消息分发实现
2023-07-11 03:15:51 深夜i     --     --
C++ 消息分发 实现 消息队列 多线程

在一个复杂的系统中,经常需要在不同的组件之间传递消息。为了处理这些消息,一个常见的解决方案是实现一个消息分发器,它负责将消息传递给正确的接收方。在C++中,可以使用各种方式实现消息分发器,下面介绍一种基于模板和函数指针的实现方式。

首先,定义一个消息分发器模板类Dispatcher,它接受两个模板参数:消息类型T和接收方类型Receiver。Dispatcher类的核心是将一个消息类型映射到一个接收方类型上,这个映射关系可以通过一个函数指针表来实现。具体地,Dispatcher类有两个成员函数:add_handler和dispatch。add_handler函数用来向函数指针表中添加一个消息处理函数,它的参数是一个指向函数的指针和一个消息类型的值。dispatch函数用来将一个消息分发给它对应的接收方,它的参数是一个消息类型T的引用和一个接收方对象的引用。

模板类Dispatcher的定义如下:

template

class Dispatcher {

public:

 using Handler = void (Receiver::*)(const T&);

 void add_handler(Handler handler, T message_type) {

  handlers_[message_type] = handler;

 }

 void dispatch(T& message, Receiver& receiver) const {

  auto it = handlers_.find(message);

  if (it != handlers_.end()) {

   (receiver.*it->second)(message);

  }

 }

private:

 std::unordered_map handlers_;

};

在上述定义中,使用了C++11提供的unordered_map容器来存储消息类型和它对应的处理函数指针。另外,Handler类型是一个指向Receiver类成员函数的指针类型,它的参数类型是一个const T&引用。

使用Dispatcher类的方式非常简单,只需要为每个接收方定义一个处理函数,并将它们添加到消息分发器中即可。下面是一个例子,演示了如何将一个整型消息分发给两个接收方:

class Receiver1 {

public:

 void on_message(const int& message)

  std::cout << "Receiver1 received message: " << message << std::endl;

};

class Receiver2 {

public:

 void on_message(const int& message)

  std::cout << "Receiver2 received message: " << message << std::endl;

};

int main() {

 Dispatcher dispatcher1;

 Receiver1 receiver1;

 dispatcher1.add_handler(&Receiver1::on_message, 1);

 Dispatcher dispatcher2;

 Receiver2 receiver2;

 dispatcher2.add_handler(&Receiver2::on_message, 1);

 int message = 42;

 dispatcher1.dispatch(message, receiver1);

 dispatcher2.dispatch(message, receiver2);

}

在上述代码中,我们定义了两个接收方Receiver1和Receiver2,它们都实现了一个处理函数on_message,用来处理整型消息。接下来,我们创建了两个消息分发器dispatcher1和dispatcher2,分别将它们与接收方receiver1和receiver2绑定。最后,我们创建了一个整型消息message,并将它分发给两个消息分发器,观察输出结果。

总体来说,C++消息分发器的实现方式有很多种,每种方式都有其优缺点。本文介绍的基于模板和函数指针的实现方式,能够很好地处理消息分发和接收方管理。当然,对于不同的场景和需求,需要根据具体情况选用适合的实现方式。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复