The Observer pattern is a behavioral design pattern where an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes. Let's implement this pattern using the this
pointer in C++:
#include <iostream>
#include <vector>
class Observer {
public:
virtual ~Observer() = default;
virtual void update(
const std::string& message) = 0;
};
class Subject {
private:
std::vector<Observer*> observers;
public:
virtual ~Subject() = default;
// Using 'this' to return the current instance
Subject* attach(Observer* observer) {
observers.push_back(observer);
return this;
}
Subject* detach(Observer* observer) {
observers.erase(std::remove(
observers.begin(), observers.end(), observer
), observers.end());
return this;
}
void notify(const std::string& message) {
for (Observer* observer : observers) {
observer->update(message);
}
}
};
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& name)
: name(name) {}
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)->attach(&observer2);
subject.notify("Hello, observers!");
subject.detach(&observer1);
subject.notify("Observer 1 has left.");
}
Observer 1 received message: Hello, observers!
Observer 2 received message: Hello, observers!
Observer 2 received message: Observer 1 has left.
In this implementation, we use the this
pointer in two key places. Firstly, in the attach()
method of the Subject
 class:
Subject* attach(Observer* observer) {
observers.push_back(observer);
return this;
}
Secondly, in the detach()
method of the Subject
 class:
Subject* detach(Observer* observer) {
observers.erase(std::remove(
observers.begin(),
observers.end(),
observer
), observers.end());
return this;
}
By returning this
, we enable method chaining, which allows for more concise and readable code when attaching or detaching multiple observers:
subject.attach(&observer1)->attach(&observer2);
This line attaches both observer1
and observer2
to the subject in a single statement.
The this
pointer is crucial here because:
Subject*
).The Observer pattern is particularly useful in scenarios where you need a one-to-many dependency between objects. For example, when an object needs to automatically notify a list of other objects about its changes, without needing to know who these objects are.
This pattern is commonly used in implementing distributed event handling systems, in Model-View-Controller (MVC) architectural patterns, and in implementing callback functionality.
Answers to questions are automatically generated and may not have been reviewed.
this
PointerLearn about the this
pointer in C++ programming, focusing on its application in identifying callers, chaining functions, and overloading operators.
Comprehensive course covering advanced concepts, and how to use them on large-scale projects.
View Course