定義物件間的一種一對多依賴關係,當一個物件狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。

std::list<Observer*>),提供 Attach/Detach/Notify 介面。Update(Subject*),具體觀察者實作更新邏輯。Observer*,不知曉具體觀察者型別;觀察者透過 Subject::GetState() 取得新狀態。Notify 時直接傳遞資料;拉模型讓觀察者主動向 Subject 索取。本實作採拉模型,彈性較高。#ifndef OBSERVER_H
#define OBSERVER_H
#include <list>
typedef int STATE;
class Observer;
class Subject {
public:
Subject() : m_nSubjectState(-1) {}
virtual ~Subject();
void Notify();
void Attach(Observer* pObserver);
void Detach(Observer* pObserver);
virtual void SetState(STATE nState);
virtual STATE GetState();
protected:
STATE m_nSubjectState;
std::list<Observer*> m_ListObserver;
};
class Observer {
public:
Observer() : m_nObserverState(-1) {}
virtual ~Observer() {}
virtual void Update(Subject* pSubject) = 0;
protected:
STATE m_nObserverState;
};
class ConcreteSubject : public Subject {
public:
ConcreteSubject() : Subject() {}
virtual ~ConcreteSubject() {}
virtual void SetState(STATE nState);
virtual STATE GetState();
};
class ConcreteObserver : public Observer {
public:
ConcreteObserver() : Observer() {}
virtual ~ConcreteObserver() {}
virtual void Update(Subject* pSubject);
};
#endif
#include "Observer.h"
#include <iostream>
#include <algorithm>
void Subject::Attach(Observer* pObserver) {
std::cout << "Attach an Observer\n";
m_ListObserver.push_back(pObserver);
}
void Subject::Detach(Observer* pObserver) {
auto iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
if (iter != m_ListObserver.end()) m_ListObserver.erase(iter);
std::cout << "Detach an Observer\n";
}
void Subject::Notify() {
std::cout << "Notify Observers's State\n";
for (auto pObs : m_ListObserver) pObs->Update(this);
}
void Subject::SetState(STATE nState) {
std::cout << "SetState By Subject\n"; m_nSubjectState = nState;
}
STATE Subject::GetState() {
std::cout << "GetState By Subject\n"; return m_nSubjectState;
}
Subject::~Subject() {
for (auto pObs : m_ListObserver) delete pObs;
m_ListObserver.clear();
}
void ConcreteSubject::SetState(STATE nState) {
std::cout << "SetState By ConcreteSubject\n"; m_nSubjectState = nState;
}
STATE ConcreteSubject::GetState() {
std::cout << "GetState By ConcreteSubject\n"; return m_nSubjectState;
}
void ConcreteObserver::Update(Subject* pSubject) {
if (!pSubject) return;
m_nObserverState = pSubject->GetState();
std::cout << "The ObserverState is " << m_nObserverState << std::endl;
}
#include "Observer.h"
#include <iostream>
int main() {
Observer* p1 = new ConcreteObserver;
Observer* p2 = new ConcreteObserver;
Subject* p = new ConcreteSubject;
p->Attach(p1); p->Attach(p2);
p->SetState(4); p->Notify(); // 兩觀察者皆更新為 4
p->Detach(p1);
p->SetState(10); p->Notify(); // 僅 p2 更新為 10
delete p;
return 0;
}
std::shared_ptr<Observer> / std::weak_ptr 管理生命週期,避免記憶體洩漏與懸空指標。std::mutex)。std::observable(實驗性)、Boost.Signals2、Qt Signals/Slots 提供更完善的訊號槽機制。