References

Implementing Observer Pattern with References

How can I use references to implement a simple observer pattern in C++?

3D character art

The Observer pattern is a software design pattern where an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes. We can implement this pattern in C++ using references for a clean and efficient design.

Here's a simple implementation:

#include <iostream>
#include <string>
#include <vector>

class Observer {
 public:
  virtual void Update(
    const std::string& message) = 0;
  virtual ~Observer() = default;
};

class Subject {
 private:
  std::vector<Observer*> observers;
  std::string state;

 public:
  void Attach(Observer& observer) {
    observers.push_back(&observer);
  }

  void Detach(Observer& observer) {
    observers.erase(std::remove(
      observers.begin(),
      observers.end(),
      &observer
    ), observers.end());
  }

  void SetState(const std::string& newState) {
    state = newState;
    Notify();
  }

  void Notify() {
    for (auto observer : observers) {
      observer->Update(state);
    }
  }
};

class ConcreteObserver : public Observer {
 private:
  std::string name;

 public:
  ConcreteObserver(const std::string& observerName)
  : name{observerName} {}

  void Update(const std::string& message) override {
    std::cout << name << " received message: "
      << message << '\n';
  }
};

int main() {
  Subject subject;

  ConcreteObserver observer1{"Observer 1"};
  ConcreteObserver observer2{"Observer 2"};

  subject.Attach(observer1);
  subject.Attach(observer2);

  subject.SetState("Hello, observers!");

  subject.Detach(observer2);

  subject.SetState("Observer 2 won't see this.");
}
Observer 1 received message: Hello, observers!
Observer 2 received message: Hello, observers!
Observer 1 received message: Observer 2 won't see this.

Let's break this down:

  1. We define an Observer interface with a pure virtual Update() method.
  2. The Subject class maintains a list of observer pointers. We use pointers here because std::vector can't store references directly.
  3. The Attach() and Detach() methods in Subject take references to Observer objects. This provides a clean syntax for the user of the class and ensures that null observers can't be attached.
  4. When SetState() is called, it updates the state and calls Notify(), which updates all observers.
  5. ConcreteObserver is an implementation of the Observer interface.
  6. In main(), we create a subject and two observers, attach the observers, set the subject's state (which notifies the observers), detach an observer, and set the state again.

Using references in the Attach() and Detach() methods provides several benefits:

  • It's more intuitive: passing by reference clearly communicates that we're working with an existing object.
  • It's safer: you can't pass a null reference, unlike with pointers.
  • It's efficient: no need to check for null before dereferencing.

Remember, while we're using references in the interface, we're storing pointers internally. This is a common pattern when you need a mutable collection of references.

Answers to questions are automatically generated and may not have been reviewed.

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

This course includes:

  • 60 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

View Course
Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2025 - All Rights Reserved