C++ 设计模式之观察者模式详细介绍

观察者模式是 行为型设计模式 的核心成员,其核心目标是:定义对象间的一对多依赖关系,当一个对象(被观察者)的状态发生变化时,所有依赖它的对象(观察者)会自动收到通知并更新

这种模式本质是"发布-订阅"机制------被观察者(发布者)无需知道具体的观察者(订阅者)是谁,只需在状态变化时广播通知,观察者按需订阅并响应。在 C++ 开发中,观察者模式广泛应用于事件驱动系统、UI 交互、状态同步、消息通知等场景(如 Qt 的信号槽机制、GUI 控件事件响应、分布式系统中的消息推送)。

本文将从 核心原理、结构组成、完整实现、进阶优化、工程实践 等维度,全面解析 C++ 观察者模式的设计与落地。

一、观察者模式的核心目标与设计思想

1.1 核心目标

  1. 解耦被观察者与观察者:被观察者无需知道观察者的具体类型和实现,仅依赖抽象接口;观察者也无需关注被观察者的内部逻辑,只需响应状态变化通知。
  2. 支持动态订阅/取消订阅:观察者可随时加入或退出订阅关系,被观察者无需修改代码即可适配。
  3. 广播通知:被观察者状态变化时,自动通知所有注册的观察者,确保状态一致性。
  4. 单一职责:被观察者负责维护状态和通知逻辑,观察者负责处理通知(如更新 UI、执行业务逻辑),各司其职。

1.2 核心设计思想

  • 依赖倒置原则:被观察者依赖观察者的抽象接口(而非具体实现),观察者依赖被观察者的抽象接口,避免紧耦合。
  • 开闭原则:新增观察者时,无需修改被观察者的代码;新增被观察者时,观察者可通过抽象接口适配,无需修改自身逻辑。
  • 事件驱动:以"状态变化"为事件,触发观察者的响应,符合事件驱动编程模型。

二、观察者模式的核心结构(4大角色)

观察者模式的结构由 4 个核心角色组成,严格遵循"依赖抽象"原则:

角色 职责描述
抽象被观察者(Subject) 定义被观察者的核心接口:注册观察者、取消注册、通知所有观察者。
具体被观察者(ConcreteSubject) 实现抽象被观察者接口,维护自身状态;状态变化时,调用通知方法触发观察者更新。
抽象观察者(Observer) 定义观察者的核心接口:接收被观察者的通知并执行更新操作(纯虚函数)。
具体观察者(ConcreteObserver) 实现抽象观察者接口,根据被观察者的通知执行具体业务逻辑(如更新 UI、记录日志)。

结构示意图

复制代码
┌─────────────────┐       ┌─────────────────┐
│  Subject(抽象) │       │  Observer(抽象)│
├─────────────────┤       ├─────────────────┤
│ + register(O)   │       │ + update()      │
│ + unregister(O) │       └─────────────────┘
│ + notify()      │                ▲
└────────┬────────┘                │
         │                         │
         ▼                         │
┌─────────────────┐       ┌─────────────────┐
│ ConcreteSubject │       │ ConcreteObserver│
├─────────────────┤       ├─────────────────┤
│ - state: T      │       │ - name: string  │
│ + getState()    │       │ + update() { ...}
│ + setState()    │       └─────────────────┘
└─────────────────┘

三、C++ 观察者模式的完整实现(基础版)

以"气象站(被观察者)+ 显示屏(观察者)"为例:气象站监测温度变化,当温度更新时,所有注册的显示屏自动显示最新温度。

3.1 步骤 1:定义抽象接口(Subject + Observer)

抽象接口是解耦的核心,确保被观察者和观察者仅依赖抽象,不依赖具体实现。

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <mutex>  // 后续线程安全用,基础版可先忽略

// 前置声明:抽象被观察者需要知道抽象观察者的存在
class Observer;

// 1. 抽象被观察者(Subject):定义核心接口
class Subject {
public:
    virtual ~Subject() = default;  // 虚析构,确保子类析构被调用

    // 注册观察者
    virtual void registerObserver(Observer* observer) = 0;

    // 取消注册观察者
    virtual void removeObserver(Observer* observer) = 0;

    // 通知所有观察者(状态变化时调用)
    virtual void notifyObservers() = 0;
};

// 2. 抽象观察者(Observer):定义更新接口
class Observer {
public:
    virtual ~Observer() = default;

    // 纯虚函数:接收被观察者的通知,执行更新操作
    // 参数:被观察者的最新状态(此处为温度,可扩展为任意类型)
    virtual void update(float temperature) = 0;

    // 可选:获取观察者名称(用于调试/识别)
    virtual std::string getName() const = 0;
};

3.2 步骤 2:实现具体被观察者(ConcreteSubject)

具体被观察者维护自身状态(温度),并实现注册、取消、通知逻辑。

cpp 复制代码
// 3. 具体被观察者:气象站(WeatherStation)
class WeatherStation : public Subject {
public:
    ~WeatherStation() override {
        std::cout << "气象站被销毁" << std::endl;
    }

    // 注册观察者:将观察者加入列表
    void registerObserver(Observer* observer) override {
        if (observer == nullptr) return;
        // 避免重复注册
        auto it = std::find(observers_.begin(), observers_.end(), observer);
        if (it == observers_.end()) {
            observers_.push_back(observer);
            std::cout << "注册观察者:" << observer->getName() << std::endl;
        }
    }

    // 取消注册:将观察者从列表中移除
    void removeObserver(Observer* observer) override {
        if (observer == nullptr) return;
        auto it = std::find(observers_.begin(), observers_.end(), observer);
        if (it != observers_.end()) {
            std::cout << "取消注册观察者:" << observer->getName() << std::endl;
            observers_.erase(it);
        }
    }

    // 通知所有观察者:遍历列表,调用每个观察者的 update 方法
    void notifyObservers() override {
        // 遍历所有注册的观察者,发送最新状态
        for (Observer* observer : observers_) {
            observer->update(current_temperature_);
        }
    }

    // 业务方法:更新气象站的温度(状态变化触发点)
    void setTemperature(float temperature) {
        if (temperature != current_temperature_) {  // 仅状态变化时通知
            current_temperature_ = temperature;
            std::cout << "\n气象站温度更新为:" << current_temperature_ << "℃" << std::endl;
            notifyObservers();  // 状态变化,通知所有观察者
        }
    }

    // 获取当前温度(可选,供观察者主动查询)
    float getTemperature() const {
        return current_temperature_;
    }

private:
    std::vector<Observer*> observers_;  // 存储注册的观察者列表
    float current_temperature_ = 0.0f;  // 被观察者的核心状态:当前温度
};

3.3 步骤 3:实现具体观察者(ConcreteObserver)

具体观察者实现 update 方法,根据被观察者的通知执行具体逻辑(如显示温度、记录日志)。

cpp 复制代码
// 4. 具体观察者1:手机显示屏(MobileDisplay)
class MobileDisplay : public Observer {
public:
    explicit MobileDisplay(std::string name) : name_(std::move(name)) {}

    ~MobileDisplay() override {
        std::cout << "手机显示屏[" << name_ << "]被销毁" << std::endl;
    }

    // 实现 update 方法:接收温度更新,显示到手机屏幕
    void update(float temperature) override {
        std::cout << "手机显示屏[" << name_ << "]:当前温度为 " << temperature << "℃" << std::endl;
    }

    std::string getName() const override {
        return "MobileDisplay-" + name_;
    }

private:
    std::string name_;  // 观察者名称(如用户ID)
};

// 5. 具体观察者2:桌面显示屏(DesktopDisplay)
class DesktopDisplay : public Observer {
public:
    explicit DesktopDisplay(std::string name) : name_(std::move(name)) {}

    ~DesktopDisplay() override {
        std::cout << "桌面显示屏[" << name_ << "]被销毁" << std::endl;
    }

    // 实现 update 方法:接收温度更新,显示到桌面屏幕
    void update(float temperature) override {
        std::cout << "桌面显示屏[" << name_ << "]:检测到温度变化,当前温度 " << temperature << "℃" << std::endl;
    }

    std::string getName() const override {
        return "DesktopDisplay-" + name_;
    }

private:
    std::string name_;
};

// 6. 具体观察者3:日志记录器(LogRecorder)
class LogRecorder : public Observer {
public:
    explicit LogRecorder(std::string log_file) : log_file_(std::move(log_file)) {}

    ~LogRecorder() override {
        std::cout << "日志记录器[" << log_file_ << "]被销毁" << std::endl;
    }

    // 实现 update 方法:记录温度变化到日志
    void update(float temperature) override {
        std::cout << "日志记录器[" << log_file_ << "]:记录温度 " << temperature << "℃(时间:2025-12-02)" << std::endl;
    }

    std::string getName() const override {
        return "LogRecorder-" + log_file_;
    }

private:
    std::string log_file_;  // 日志文件名
};

3.4 步骤 4:测试代码(验证观察者模式)

cpp 复制代码
int main() {
    // 1. 创建被观察者:气象站
    WeatherStation weather_station;

    // 2. 创建观察者:3个显示屏 + 1个日志记录器
    MobileDisplay mobile1("用户A");
    MobileDisplay mobile2("用户B");
    DesktopDisplay desktop("办公室");
    LogRecorder log_recorder("temperature.log");

    // 3. 注册观察者到气象站
    weather_station.registerObserver(&mobile1);
    weather_station.registerObserver(&mobile2);
    weather_station.registerObserver(&desktop);
    weather_station.registerObserver(&log_recorder);

    // 4. 气象站温度变化(触发通知)
    weather_station.setTemperature(25.5f);
    weather_station.setTemperature(26.0f);  // 再次变化
    weather_station.setTemperature(26.0f);  // 温度不变,不通知

    // 5. 取消某个观察者的注册
    std::cout << "\n--- 取消注册用户B的手机显示屏 ---" << std::endl;
    weather_station.removeObserver(&mobile2);

    // 6. 温度再次变化(取消注册的观察者不再收到通知)
    weather_station.setTemperature(27.3f);

    return 0;
}

3.5 运行结果与分析

复制代码
注册观察者:MobileDisplay-用户A
注册观察者:MobileDisplay-用户B
注册观察者:DesktopDisplay-办公室
注册观察者:LogRecorder-temperature.log

气象站温度更新为:25.5℃
手机显示屏[用户A]:当前温度为 25.5℃
手机显示屏[用户B]:当前温度为 25.5℃
桌面显示屏[办公室]:检测到温度变化,当前温度 25.5℃
日志记录器[temperature.log]:记录温度 25.5℃(时间:2025-12-02)

气象站温度更新为:26.0℃
手机显示屏[用户A]:当前温度为 26.0℃
手机显示屏[用户B]:当前温度为 26.0℃
桌面显示屏[办公室]:检测到温度变化,当前温度 26.0℃
日志记录器[temperature.log]:记录温度 26.0℃(时间:2025-12-02)

--- 取消注册用户B的手机显示屏 ---
取消注册观察者:MobileDisplay-用户B

气象站温度更新为:27.3℃
手机显示屏[用户A]:当前温度为 27.3℃
桌面显示屏[办公室]:检测到温度变化,当前温度 27.3℃
日志记录器[temperature.log]:记录温度 27.3℃(时间:2025-12-02)

日志记录器[temperature.log]被销毁
桌面显示屏[办公室]被销毁
手机显示屏[用户B]被销毁
手机显示屏[用户A]被销毁
气象站被销毁
关键结论:
  1. 被观察者状态变化时,所有注册的观察者自动收到通知(update 方法被调用)。
  2. 观察者可动态注册/取消注册,不影响被观察者和其他观察者。
  3. 被观察者与观察者通过抽象接口解耦:新增观察者(如 TVDisplay)时,无需修改 WeatherStation 代码。

四、C++ 观察者模式的核心问题与进阶优化

基础版实现满足基本需求,但在工程实践中需解决 线程安全、状态传递、内存管理、灵活性 等问题,以下是关键优化点:

4.1 优化 1:线程安全(多线程场景必备)

基础版中,observers_ 列表的读写(注册、取消、通知)若在多线程环境下执行(如一个线程更新温度,另一个线程注册观察者),会导致数据竞争(vector 非线程安全)。

解决方案:添加互斥锁(std::mutex
cpp 复制代码
class WeatherStation : public Subject {
public:
    // ... 其他方法不变 ...

    void registerObserver(Observer* observer) override {
        std::lock_guard<std::mutex> lock(mutex_);  // 加锁保护
        if (observer == nullptr) return;
        auto it = std::find(observers_.begin(), observers_.end(), observer);
        if (it == observers_.end()) {
            observers_.push_back(observer);
            std::cout << "注册观察者:" << observer->getName() << std::endl;
        }
    }

    void removeObserver(Observer* observer) override {
        std::lock_guard<std::mutex> lock(mutex_);  // 加锁保护
        if (observer == nullptr) return;
        auto it = std::find(observers_.begin(), observers_.end(), observer);
        if (it != observers_.end()) {
            std::cout << "取消注册观察者:" << observer->getName() << std::endl;
            observers_.erase(it);
        }
    }

    void notifyObservers() override {
        std::lock_guard<std::mutex> lock(mutex_);  // 加锁保护
        // 复制观察者列表(避免通知过程中列表被修改,如观察者取消注册)
        std::vector<Observer*> temp_observers = observers_;
        lock.unlock();  // 提前解锁,减少阻塞时间

        for (Observer* observer : temp_observers) {
            observer->update(current_temperature_);
        }
    }

private:
    std::vector<Observer*> observers_;
    float current_temperature_ = 0.0f;
    std::mutex mutex_;  // 保护观察者列表的线程安全锁
};
关键优化点:
  • std::lock_guard 自动加锁/解锁,避免死锁。
  • 通知时复制观察者列表:防止通知过程中观察者取消注册导致 vector 迭代器失效。

4.2 优化 2:灵活传递状态(支持多状态/任意类型)

基础版中 update 方法仅传递 temperature(单一状态),实际场景中被观察者可能有多个状态(如温度、湿度、气压),需支持灵活传递。

解决方案 1:传递被观察者指针(观察者主动查询)

观察者通过被观察者指针,按需查询所需状态,避免 update 方法参数膨胀:

cpp 复制代码
// 修改抽象观察者的 update 方法
class Observer {
public:
    virtual ~Observer() = default;
    // 传递被观察者指针,观察者主动查询状态
    virtual void update(Subject* subject) = 0;
    virtual std::string getName() const = 0;
};

// 具体观察者实现(以 MobileDisplay 为例)
void MobileDisplay::update(Subject* subject) override {
    // 向下转型(需确保安全,可加 dynamic_cast 校验)
    WeatherStation* station = dynamic_cast<WeatherStation*>(subject);
    if (station != nullptr) {
        float temp = station->getTemperature();
        std::cout << "手机显示屏[" << name_ << "]:当前温度为 " << temp << "℃" << std::endl;
    }
}

// 被观察者通知逻辑修改
void WeatherStation::notifyObservers() override {
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<Observer*> temp_observers = observers_;
    lock.unlock();

    for (Observer* observer : temp_observers) {
        observer->update(this);  // 传递自身指针
    }
}
解决方案 2:使用结构体/变体(传递多状态)

struct 封装多个状态,或用 C++17 的 std::variant 支持任意类型状态:

cpp 复制代码
// 定义状态结构体
struct WeatherState {
    float temperature;
    float humidity;
    float pressure;
};

// 抽象观察者 update 方法
virtual void update(const WeatherState& state) = 0;

// 被观察者通知时传递状态结构体
void WeatherStation::notifyObservers() override {
    WeatherState state = {current_temperature_, current_humidity_, current_pressure_};
    for (Observer* observer : temp_observers) {
        observer->update(state);
    }
}

4.3 优化 3:内存管理(避免野指针/内存泄漏)

基础版中,被观察者存储观察者的裸指针(Observer*),若观察者被销毁但未取消注册,被观察者会继续调用裸指针的 update 方法,导致野指针崩溃。

解决方案 1:使用智能指针(std::shared_ptr/std::weak_ptr

推荐用 std::weak_ptr 存储观察者(避免循环引用),观察者通过 std::shared_ptr 管理自身生命周期:

cpp 复制代码
#include <memory>

// 抽象观察者不变,具体观察者用 shared_ptr 管理
class MobileDisplay : public Observer, public std::enable_shared_from_this<MobileDisplay> {
    // ... 实现不变 ...
};

// 被观察者存储 weak_ptr(不影响观察者生命周期)
class WeatherStation : public Subject {
private:
    std::vector<std::weak_ptr<Observer>> observers_;  // 弱指针列表
    // ... 其他成员不变 ...
};

// 注册观察者(接收 shared_ptr)
void WeatherStation::registerObserver(std::shared_ptr<Observer> observer) {
    if (!observer) return;
    std::lock_guard<std::mutex> lock(mutex_);
    observers_.push_back(observer);  // weak_ptr 自动从 shared_ptr 转换
}

// 通知观察者(先锁定 weak_ptr,判断观察者是否存活)
void WeatherStation::notifyObservers() override {
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<std::weak_ptr<Observer>> temp_observers = observers_;
    lock.unlock();

    for (auto& weak_observer : temp_observers) {
        // 锁定 weak_ptr,判断观察者是否还存活
        if (auto observer = weak_observer.lock()) {
            observer->update(this);
        }
    }
}

// 测试代码中创建观察者
auto mobile1 = std::make_shared<MobileDisplay>("用户A");
weather_station.registerObserver(mobile1);
关键优势:
  • 观察者被销毁时,weak_ptr 会自动失效,通知时不会调用已销毁的观察者。
  • 避免循环引用:被观察者用 weak_ptr 引用观察者,观察者无需引用被观察者,无循环依赖。

4.4 优化 4:支持带参数的观察者(灵活响应)

实际场景中,观察者可能需要自定义响应逻辑(如"温度超过 30℃ 时才报警"),可让观察者注册时传递过滤条件或回调函数。

解决方案:观察者注册时传递回调函数
cpp 复制代码
#include <functional>

// 定义回调函数类型:接收温度,返回是否处理
using UpdateCallback = std::function<void(float temperature)>;

// 抽象观察者扩展:支持回调函数
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(float temperature) = 0;
    virtual std::string getName() const = 0;
    // 可选:设置回调函数
    virtual void setCallback(UpdateCallback callback) {
        callback_ = std::move(callback);
    }

protected:
    UpdateCallback callback_;
};

// 具体观察者使用回调函数
class AlarmDisplay : public Observer {
public:
    explicit AlarmDisplay(std::string name) : name_(std::move(name)) {}

    void update(float temperature) override {
        if (callback_) {
            callback_(temperature);  // 执行回调函数
        }
    }

    std::string getName() const override {
        return "AlarmDisplay-" + name_;
    }

private:
    std::string name_;
};

// 测试代码:注册时设置回调(温度>30℃报警)
auto alarm = std::make_shared<AlarmDisplay>("卧室");
alarm->setCallback([](float temp) {
    if (temp > 30.0f) {
        std::cout << "⚠️  温度报警:当前温度 " << temp << "℃,超过阈值!" << std::endl;
    }
});
weather_station.registerObserver(alarm);

// 触发报警
weather_station.setTemperature(31.2f);  // 输出报警信息

4.5 优化 5:事件类型过滤(观察者仅关注特定事件)

被观察者可能产生多种事件(如"温度变化""湿度变化"),观察者可能只关注其中一种,需支持事件类型过滤。

解决方案:定义事件类型枚举,观察者注册时指定关注的事件
cpp 复制代码
// 定义事件类型
enum class EventType {
    TEMPERATURE_CHANGED,
    HUMIDITY_CHANGED,
    PRESSURE_CHANGED
};

// 抽象观察者更新方法添加事件类型参数
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(EventType event, const WeatherState& state) = 0;
    virtual std::string getName() const = 0;
    // 获取观察者关注的事件类型
    virtual std::vector<EventType> getInterestedEvents() const = 0;
};

// 具体观察者(仅关注温度变化)
class TemperatureDisplay : public Observer {
public:
    std::vector<EventType> getInterestedEvents() const override {
        return {EventType::TEMPERATURE_CHANGED};
    }

    void update(EventType event, const WeatherState& state) override {
        if (event == EventType::TEMPERATURE_CHANGED) {
            std::cout << "温度显示屏:当前温度 " << state.temperature << "℃" << std::endl;
        }
    }

    // ... 其他实现 ...
};

// 被观察者通知时,仅通知关注该事件的观察者
void WeatherStation::notifyObservers(EventType event) {
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<std::weak_ptr<Observer>> temp_observers = observers_;
    lock.unlock();

    WeatherState state = {current_temperature_, current_humidity_, current_pressure_};
    for (auto& weak_observer : temp_observers) {
        if (auto observer = weak_observer.lock()) {
            // 检查观察者是否关注该事件
            auto interested = observer->getInterestedEvents();
            if (std::find(interested.begin(), interested.end(), event) != interested.end()) {
                observer->update(event, state);
            }
        }
    }
}

// 温度变化时,触发对应事件通知
void WeatherStation::setTemperature(float temperature) {
    if (temperature != current_temperature_) {
        current_temperature_ = temperature;
        notifyObservers(EventType::TEMPERATURE_CHANGED);  // 指定事件类型
    }
}

五、观察者模式的适用场景与反场景

5.1 适用场景

  1. 事件驱动系统:如 GUI 框架(按钮点击、窗口关闭等事件)、游戏引擎(角色移动、碰撞检测事件)。
  2. 状态同步场景:如分布式系统中的数据同步(主节点状态变化,从节点自动同步)、缓存更新(数据源变化,缓存自动刷新)。
  3. 消息通知场景:如日志系统(核心模块状态变化,日志模块自动记录)、报警系统(监控指标异常,报警模块自动通知)。
  4. 解耦需求场景:被观察者和观察者需要解耦,避免紧耦合(如业务模块与通知模块分离)。

5.2 反场景(不建议使用)

  1. 观察者数量极少且固定:如仅 1-2 个观察者,且不会扩展,直接调用函数比观察者模式更简洁。
  2. 同步更新开销过大:如观察者更新逻辑复杂(耗时久),且需同步执行,会导致被观察者阻塞(可改用异步通知解决)。
  3. 循环依赖风险:被观察者和观察者相互引用,可能导致内存泄漏(需用弱指针等方式避免)。
  4. 状态变化过于频繁:如每秒上千次状态变化,观察者频繁更新会导致系统性能下降(需合并通知或节流)。

六、C++ 成熟库中的观察者模式应用

  1. Qt 框架QObject + 信号槽(signals/slots)是观察者模式的经典实现,支持跨线程通知、自动连接/断开,是 Qt 的核心机制。

    cpp 复制代码
    // Qt 信号槽示例(本质是观察者模式)
    class WeatherStation : public QObject {
        Q_OBJECT
    signals:
        void temperatureChanged(float temperature);  // 信号(被观察者通知)
    public:
        void setTemperature(float temp) {
            emit temperatureChanged(temp);  // 触发信号
        }
    };
    
    class Display : public QObject {
        Q_OBJECT
    public slots:
        void onTemperatureChanged(float temp) {  // 槽函数(观察者更新)
            qDebug() << "当前温度:" << temp;
        }
    };
    
    // 连接信号槽(注册观察者)
    WeatherStation station;
    Display display;
    QObject::connect(&station, &WeatherStation::temperatureChanged, &display, &Display::onTemperatureChanged);
  2. Boost 库boost::signals2 提供线程安全的观察者模式实现,支持多播回调、自动管理连接,兼容 C++11 及以上标准。

  3. C++ 标准库 :无原生观察者模式实现,但可通过 std::function + std::vector 快速实现轻量级观察者模式(如回调列表)。

七、总结与核心原则

观察者模式的核心是 "解耦发布者与订阅者,支持动态联动",C++ 实现的关键在于:

  1. 依赖抽象接口(Subject/Observer),避免紧耦合。
  2. 解决线程安全、内存管理、状态传递等工程问题。
  3. 结合 C++ 特性(智能指针、互斥锁、变体、函数对象)提升灵活性和安全性。

核心原则

  1. 开闭原则优先:新增观察者/被观察者时,无需修改现有代码。
  2. 最小知识原则:被观察者仅通知必要信息,观察者无需了解被观察者内部逻辑。
  3. 线程安全不可少:多线程场景下必须加锁保护观察者列表。
  4. 内存安全是底线:避免裸指针野指针,优先使用智能指针管理生命周期。

在实际开发中,若需快速实现,可基于 std::function + std::vector 实现轻量级版本;若需工业级稳定性,可使用 Qt 信号槽或 Boost.Signals2;若需自定义灵活扩展,可基于本文的进阶优化方案实现。观察者模式是 C++ 事件驱动编程的基础,掌握其设计思想和工程实践,能有效提升代码的解耦度和可维护性。

相关推荐
西幻凌云39 分钟前
认识STLstack容器
c++·stl·适配器·stack·序列式容器
Iris76139 分钟前
Linux 多网口路由配置实践:解决双网口通讯问题
linux
软件测试慧姐40 分钟前
精简版-Linux常用命令
linux·运维·服务器
威桑41 分钟前
一个 CMake 项目是否只能有一个 install 目录?
linux·c++·cmake
爪哇部落算法小助手44 分钟前
每日两题day61
数据结构·c++·算法
大聪明-PLUS44 分钟前
FFmpeg 组件 - 用途、输入/输出数据、配置
linux·嵌入式·arm·smarc
讨厌下雨的天空44 分钟前
Linux信号中断
linux
a3158238061 小时前
Linux部署Python Django工程和Node工程,使用宝塔面板
linux·服务器·python·django·node·strapi·宝塔面板
曼巴UE51 小时前
UE5 C++ 多播绑定执行演示
c++·ue5