发布订阅者模式c++实现


#ifndef BOTTON_H
#define BOTTON_H

#include <string>
#include <vector>

class BottonListener;
class Botton
{
public:
 Botton(const std::string & botton_name);
 ~Botton();
 const std::string & GetName() const;
 void AddBottonListener(BottonListener * botton_listener);
 void RemoveBottonListenner(BottonListener * botton_listener);
 void Run();
private:
 typedef std::vector<BottonListener*>::iterator ITER;
 std::string name_;
 std::vector<BottonListener*> listener_vector_;
};
#endif/*BOTTON_H*/

 

 


#ifndef BOTTON_LISTENER_H
#define BOTTON_LISTENER_H

class Botton;
class BottonListener
{
public:
 BottonListener();
 virtual ~BottonListener();
 virtual void BottonClick(Botton * botton) = 0;
};
#endif/*BOTTON_LISTENER_H*/

 

 

#ifndef MY_BOTTON_LISTENER_H
#define MY_BOTTON_LISTENER_H

#include "botton_listener.h"
#include "botton.h"

class MyBottonListener : public BottonListener
{
public:
 MyBottonListener(int number);
 ~MyBottonListener();
 void BottonClick(Botton * botton);
private:
 int number_;
};

#endif/*MY_BOTTON_LISTENER_H*/

 


#include "botton_listener.h"
#include "botton.h"

Botton::Botton(const std::string &botton_name) : name_(botton_name)
{

}

Botton::~Botton()
{

}

const std::string & Botton::GetName() const
{
 return this->name_;
}

void Botton::AddBottonListener(BottonListener * botton_listener)
{
 this->listener_vector_.push_back(botton_listener);
}

void Botton::RemoveBottonListenner(BottonListener * botton_listener)
{
 bool key = false;
 ITER iter;
 for(iter = listener_vector_.begin();iter != listener_vector_.end();iter++)
 {
  if(*iter == botton_listener )
  {
   key = true;
   break;
  }
 }
 if(key)
 {
  listener_vector_.erase(iter);
 }
}

void Botton::Run()
{
 for(ITER iter = listener_vector_.begin(); iter != listener_vector_.end(); iter++)
 {
  BottonListener * p_botton_listener = *iter;
  p_botton_listener->BottonClick(this);
 }
}

 

 

#include "botton_listener.h"

BottonListener::BottonListener()
{

}

BottonListener::~BottonListener()
{

}

 


#include <iostream>
#include "my_botton_listener.h"

MyBottonListener::MyBottonListener(int number) : number_(number)
{

}

MyBottonListener::~MyBottonListener()
{

}

void MyBottonListener::BottonClick(Botton *botton)
{
 std::cout<<botton->GetName()<<" "<<number_<<std::endl;
}


 


#include "botton_listener.h"
#include "botton.h"
#include "my_botton_listener.h"

int main(int argc,char **argv)
{
 Botton *botton = new Botton("Hello!");
 BottonListener *botton_listener_1 = new MyBottonListener(1);
 BottonListener *botton_listener_2 = new MyBottonListener(2);

 botton->AddBottonListener(botton_listener_1);
 botton->AddBottonListener(botton_listener_2);

 botton->Run();
 
 botton->RemoveBottonListenner(botton_listener_1);
 botton->RemoveBottonListenner(botton_listener_2);
 delete botton;
 delete botton_listener_1;
 delete botton_listener_2;

}

 

 

发布订阅模式是一种消息通信模式,其中发送者(发布者)向所有已订阅的接收者(订阅者)发送消息。订阅者注册的兴趣被维护在 PubSub 系统的一个目录中,通常使用 topics 或者 channels 来对消息进行分类。 下面是使用 C 语言实现发布订阅模式的代码示例: ``` #include <stdio.h> #define MAX_TOPICS 100 #define MAX_SUBSCRIBERS 10 typedef struct { char name[20]; void (*func)(char*); } subscriber; typedef struct { char name[20]; subscriber subs[MAX_SUBSCRIBERS]; int num_subs; } topic; topic topics[MAX_TOPICS]; int num_topics = 0; void subscribe(char *topic_name, subscriber s) { int i, topic_index = -1; // Find the topic index for (i = 0; i < num_topics; i++) { if (strcmp(topics[i].name, topic_name) == 0) { topic_index = i; break; } } // If the topic doesn't exist, create it if (topic_index == -1) { strcpy(topics[num_topics].name, topic_name); topic_index = num_topics; num_topics++; } // Add the subscriber to the topic topics[topic_index].subs[topics[topic_index].num_subs] = s; topics[topic_index].num_subs++; } void publish(char *topic_name, char *message) { int i, j, topic_index = -1; // Find the topic index for (i = 0; i < num_topics; i++) { if (strcmp(topics[i].name, topic_name) == 0) { topic_index = i; break; } } // If the topic doesn't exist, return if (topic_index == -1) { return; } // Call the subscriber functions for (j = 0; j < topics[topic_index].num_subs; j++) { topics[topic_index].subs[j].func(message); } } // Example usage void print_message(char *message) { printf("%s\n", message); } int main() { subscriber s1 = {"Subscriber 1", print_message}; subscriber s2 = {"Subscriber 2", print_message}; subscribe("topic1", s1); subscribe("topic1", s2); subscribe("topic2", s2); publish("topic1", "Hello world!"); publish("topic2", "Goodbye world!"); return 0; } ``` 在此代码中,我们创建了两个结构体:`subscriber` 和 `topic`。每个 `subscriber` 包含一个名称和一个函数指针,该函数指针将在发布时调用。每个 `topic` 包含一个名称和一个数组,该数组存储了订阅该主题的所有订阅者。 我们实现了两个函数:`subscribe()` 和 `publish()`。`subscribe()` 函数接受一个主题名称和一个订阅者作为参数,并将订阅者添加到该主题的 `subs` 数组中。如果主题不存在,则创建一个新主题。`publish()` 函数接受一个主题名称和一条消息作为参数,并调用订阅该主题的每个订阅者的函数,将该消息作为参数传递给它们。 最后我们通过一个示例演示了一个订阅订阅两个不同的主题,发布发布给他们不同的消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值