Skip to content

Instantly share code, notes, and snippets.

@bosley
Created April 2, 2020 17:14
Show Gist options
  • Save bosley/6e844b7d0f53e807fed0fd8c33828e80 to your computer and use it in GitHub Desktop.
Save bosley/6e844b7d0f53e807fed0fd8c33828e80 to your computer and use it in GitHub Desktop.
A simple pubsub example using an interface in C++
#include <iostream>
#include <string>
#include <vector>
namespace {
// An interface for objects that want to 'be' subscribers
class SubscriberIf {
public:
virtual void recvPublishedData(std::string data) = 0;
};
// An object that published data to subscriber interfaces
class Publisher {
public:
Publisher() {
}
// Check how many subscribers the publisher has
int getSubscriberCount() const {
return subscribers.size();
}
// We don't want to allow nullptrs, so we ensure the existence of a subscriber by
// enforcing a reference.
void registerSubscriber(SubscriberIf & subscriber) {
// Because we store pointers, and have a reference, we need to make it a pointer so we add '&'
subscribers.push_back(&subscriber);
}
void publishData(std::string data) {
// Go through list of subscribers, and send them the data
for(auto &subscriber : subscribers) {
subscriber->recvPublishedData(data);
}
}
private:
// We store pointers, because we can't directly store a virtual object
std::vector<SubscriberIf*> subscribers;
};
// --------------------------------------------------------------------------------------------------
//
// Implementations of subscribers
//
// --------------------------------------------------------------------------------------------------
class SomeSubscriber : public SubscriberIf {
public:
// Construct a subscriber and set its name
SomeSubscriber(std::string name) : name(name) {
}
// From SubscriberIf
virtual void recvPublishedData(std::string data) override {
std::cout << "Subscriber [" << name << "] received : " << data << std::endl;
}
private:
std::string name;
};
class SpecialSubscriber : public SubscriberIf {
public:
// Construct a subscriber and set its name
SpecialSubscriber(std::string name) : name(name) {
}
// From SubscriberIf
virtual void recvPublishedData(std::string data) override {
std::cout << "Special Subscriber [" << name << "] received : " << data << std::endl;
}
private:
std::string name;
};
}
int main() {
Publisher myPublisher;
SomeSubscriber a("Subscriber A");
SomeSubscriber b("Subscriber B");
SomeSubscriber c("Subscriber C");
SpecialSubscriber specialA("wicked");
SpecialSubscriber specialB("wild");
SpecialSubscriber specialC("far-out");
// Since all six of the objects above inherit the SubscriberIf, we can pass them to registerSubscriber
// that will allow myPublisher to execute the methods made avaiable from SubscriberIf
// Note: The publisher won't be able to access any methods on the given objects other than those inherited from
// SubscriberIf as they are 'sliced' off or 'lost' by us only passing the objects in as SubscriberIfs
myPublisher.registerSubscriber(a);
myPublisher.registerSubscriber(b);
myPublisher.registerSubscriber(c);
myPublisher.registerSubscriber(specialA);
myPublisher.registerSubscriber(specialB);
myPublisher.registerSubscriber(specialC);
std::cout << "Publisher has : " << myPublisher.getSubscriberCount() << " subscribers" << std::endl;
myPublisher.publishData("Some data that everyone cares about");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment