观察者模式在C++中通过抽象基类解耦Subject与Observer,用std::vector+weak_ptr管理观察者并自动清理,模板化SubjectBase提升复用性,具体类仅需继承并调用notify(),新增观察者零侵入。

观察者模式在C++中核心是解耦“被观察者”(Subject)和“观察者”(Observer),让两者只依赖抽象,不依赖具体实现。关键在于用抽象类定义接口、用容器管理观察者、用虚函数触发通知——不用信号槽、不依赖第三方库,纯标准C++就能落地。
定义抽象观察者和被观察者接口
先写两个纯虚基类:Observer 声明 update() 接口,Subject 声明 attach()/detach()/notify() 接口。所有具体类都继承它们,这样新增观察者或被观察者时,原有代码完全不用改。
注意:Observer 的 update() 通常接收 const Subject& 或 shared_ptr
实现可复用的 Subject 基类模板
把通用逻辑抽成模板,减少重复代码。例如:
立即学习“C++免费学习笔记(深入)”;
// 模板化 Subject 基类,自动管理 weak_ptr 观察者
template
class SubjectBase {
protected:
std::vector<:weak_ptr>> observers_;
public:
void attach(std::shared_ptr
observers_.push_back(obs);
}
void notify() const {
for (auto it = observers_.begin(); it != observers_.end();) {
if (auto obs = it->lock()) {
obs->update(*this);
++it;
} else {
it = observers_.erase(it); // 自动清理已销毁的观察者
}
}
}
};
具体业务类按需继承并触发通知
比如一个温度传感器类:
class TemperatureSensor : public SubjectBase
private:
double temperature_ = 0.0;
public:
void setTemperature(double t) {
temperature_ = t;
notify(); // 数据一变就广播,不关心谁在监听
}
double getTemperature() const { return temperature_; }
};
再写具体观察者,比如控制台打印器和日志记录器,都只实现自己的 update(),互不影响:
- ConsoleDisplay::update() —— printf 当前温度
- Logger::update() —— 写入文件或发网络请求
使用时只需组合,不修改已有类
main() 里创建对象、建立关系即可:
int main() {
auto sensor = std::make_shared
auto display = std::make_shared
auto logger = std::make_shared
sensor->attach(display);
sensor->attach(logger);
sensor->setTemperature(25.6); // 自动触发 display 和 logger
sensor->setTemperature(26.1); // 同样自动通知
}
以后加新功能(比如发邮件告警),只要写个 EmailAlert 类继承 Observer,实现 update(),再 attach 进去——零侵入、无编译依赖、职责清晰。
基本上就这些。不复杂但容易忽略 weak_ptr 清理、const 正确性、以及模板接口的泛化粒度。写熟了,一个项目里几十个松耦合的通知场景,都能靠这几行基类搞定。










