Created
April 2, 2020 17:14
-
-
Save bosley/6e844b7d0f53e807fed0fd8c33828e80 to your computer and use it in GitHub Desktop.
A simple pubsub example using an interface in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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