注意 subject & observer 通通都是 shared pointer!不行使用 unique pointer,因為 SubscribeUnsubscribe 都會需要用到 smart pointer 形式的 this pointer,會需要用到 shared_from_this()(詳見 Smart Pointers ),和

class Observer : public IObserver, public std::enable_shared_from_this<Observer> 

Observer 當中有個 private member std::weak_ptr<Subject> subject_;,用來追蹤 Subject(which is a shared pointer),並判斷是否已經 subscribe & unsubscribe。

#include <iostream>
#include <list>
#include <string>
#include <memory>
 
class IObserver {
 public:
  virtual ~IObserver(){};
  virtual void Update(const std::string &message_from_subject) = 0;
};
 
class ISubject {
 public:
  virtual ~ISubject(){};
  virtual void Attach(std::shared_ptr<IObserver> observer) = 0;
  virtual void Detach(std::shared_ptr<IObserver> observer) = 0;
  virtual void Notify() = 0;
};
 
class Subject : public ISubject {
 public:
  virtual ~Subject() {
    std::cout << "Goodbye, I was the Subject.\n";
  }
 
  void Attach(std::shared_ptr<IObserver> observer) override {
    list_observer_.push_back(observer);
  }
  void Detach(std::shared_ptr<IObserver> observer) override {
    list_observer_.remove(observer);
  }
  
  void Notify() override {
    std::cout << "Notify currently " << list_observer_.size() << " observers in the list\n";
    for (auto observer: list_observer_) {
      observer->Update(message_);
    }
  }
 
  void CreateMessage(std::string message = "Empty") {
    this->message_ = message;
    Notify();
  }
 
  /**
   * Usually, the subscription logic is only a fraction of what a Subject can
   * really do. Subjects commonly hold some important business logic, that
   * triggers a notification method whenever something important is about to
   * happen (or after it).
   */
  void SomeBusinessLogic() {
    this->message_ = "change message message";
    std::cout << "Some business logic has been implemented, a new message should be available for you all\n";
    Notify();
  }
 
 private:
  std::list<std::shared_ptr<IObserver>> list_observer_;
  std::string message_;
};
 
class Observer : public IObserver, public std::enable_shared_from_this<Observer>  {
 public:
  Observer() {
    std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
    this->number_ = Observer::static_number_;
  }
 
  virtual ~Observer() {
    std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
  }
  
  void Subscribe(std::shared_ptr<Subject> subject) {
    if(auto s = subject_.lock()) {
        std::cout << "(Observer " << number_ << "): Already subscribed.\n";
    } else {
        subject_ = subject;
        subject->Attach(shared_from_this());
    }
  }
 
  void Unsubscribe(std::shared_ptr<Subject> subject) {
    if(auto s = subject_.lock()) {
        subject->Detach(shared_from_this());
        subject_.reset();
    } else {
        std::cout << "(Observer " << number_ << "): Already Unsubscribed.\n";
    }
  }
 
  void Update(const std::string &message_from_subject) override {
    message_from_subject_ = message_from_subject;
    PrintInfo();
  }
 
  void PrintInfo() {
    std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
  }
 
 private:
  std::string message_from_subject_;
  std::weak_ptr<Subject> subject_;
  static int static_number_;
  int number_;
};
 
int Observer::static_number_ = 0;
 
void ClientCode() {
 
  auto subject = std::make_shared<Subject>(); 
  auto observer1 = std::make_shared<Observer>();
  observer1->Subscribe(subject);
  auto observer2 = std::make_shared<Observer>();
  observer2->Subscribe(subject);
  auto observer3 = std::make_shared<Observer>();
  observer3->Subscribe(subject);
  
  subject->CreateMessage("Hello World! :D");
  observer3->Unsubscribe(subject);
 
  subject->CreateMessage("The weather is hot today! :p");
  
  auto observer4 = std::make_shared<Observer>();
  observer4->Subscribe(subject);
  auto observer5 = std::make_shared<Observer>();
  observer5->Subscribe(subject);
 
  subject->SomeBusinessLogic();
 
}
 
int main() {
  ClientCode();
  return 0;
}

Reference