You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

观察者模式:不将Subject设为模板类,如何传递模板变量给Observer?

解决方案:通过非模板基类+动态类型转换实现

你的核心问题是非模板类Subject无法存储模板化的Observer指针,因为Subject本身没有模板参数T,导致std::vector<Observer<T>*>中的T无定义。下面给出一种简洁的解决思路,无需将Subject改为模板类:

核心思路

引入一个非模板的抽象基类BaseObserver,让所有模板化的Observer<T>继承它。这样Subject只需存储BaseObserver*的容器,在notify时通过动态类型转换筛选出匹配类型的观察者,调用其模板化的update方法。

完整可编译代码

#include <iostream>
#include <vector>

class Subject;

// 所有观察者的非模板基类,仅提供统一销毁接口
class BaseObserver {
public:
    virtual ~BaseObserver() = default;
};

template<typename T>
class Observer : public BaseObserver {
public:
    virtual void update(T value, Subject*) = 0;
};

class Subject {
private:
    std::vector<BaseObserver*> _obs;

public:
    void attach(BaseObserver* obs) {
        _obs.push_back(obs);
    }

    template<typename T>
    void notify(T value) {
        for (auto obs : _obs) {
            // 仅通知类型匹配的观察者
            if (auto typed_obs = dynamic_cast<Observer<T>*>(obs)) {
                typed_obs->update(value, this);
            }
        }
    }
};

template<typename T>
class B : public Observer<T> {
public:
    void update(T value, Subject* sub) override {
        std::cout << "Value set = " << value << std::endl;
    }
};

template<typename T>
class A : public Subject {
private:
    T _x;

public:
    void set(T value) {
        _x = value;
        notify(_x); // 直接传递模板类型值,Subject无需模板化
    }
};

int main() {
    A<int> a1;
    B<int> b1;
    B<double> b2; // 测试不同类型观察者,不会收到int通知

    a1.attach(&b1);
    a1.attach(&b2);
    a1.set(10); // 仅b1输出:Value set = 10

    A<double> a2;
    a2.attach(&b2);
    a2.set(3.14); // 仅b2输出:Value set = 3.14

    return 0;
}

关键细节说明

  1. 非模板基类BaseObserver:解决Subject无法存储模板化Observer的问题,提供统一的基类指针类型,同时保证多态销毁避免内存泄漏。
  2. 动态类型转换dynamic_cast:在notify时筛选出与当前value类型匹配的Observer,确保只有对应类型的观察者会收到通知,保证类型安全。
  3. 模板化的notify函数:Subject的notify是模板函数,支持任意类型的value传递,无需Subject本身模板化。

注意:使用dynamic_cast需要编译器开启RTTI(运行时类型信息),主流编译器默认已开启,若需手动开启可添加编译选项(如GCC的-frtti)。

内容的提问来源于stack exchange,提问作者xyf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:54:22