在C++中实现了Observer模式

implementing Observer pattern in C++

本文关键字:Observer 模式 实现 C++      更新时间:2023-10-16

我正在用C++编写一个非常简单的Observer模式实现。因为我希望我的发布服务器用不同的事件(例如,不仅仅是一个字符串,而是一个特定的类)通知它的订阅者,所以我决定使用模板。我的代码编译得很好,除了我不知道将所有这些Observer存储在哪里的部分。如果我使用和std::list或std::vector,它们将不允许存储专用数据,因为它们的元素必须相同。所以我的问题是,如何在Publisher类中存储所有这些观察者。这是我的代码:

Observer.hpp
#ifndef H_OBSERVER
#define H_OBSERVER    
#include <memory>
class Publisher;
template <class T>
class Observer
{
    protected:
    virtual void Notify(std::shared_ptr<Publisher> source, T info) = 0;
};
#endif
Publisher.hpp
#ifndef H_PUBLISHER
#define H_PUBLISHER
#include "Observer.hpp"
#include <list>
#include <string>
#include <memory>
class Publisher
{
public:
    template<class T>
    void NotifyObservers();
    template <class T>
    void AddObserver(std::shared_ptr<Observer<T>> &obs);
    template <class T>
    void RemoveObserver(std::shared_ptr<Observer<T>> &obs);
protected:
    //std::list<std::shared_ptr<Observer> m_observers;
};
#endif

将观察者保存在std::vector这样的标准容器中。

对于生命周期管理和标识,请使用:std::weak_pointer
对于多态函数(对象),std::function
并使用CCD_ 4将它们组合在一起。

这意味着您可以废弃非标准的Observer

我发布的初始解决方案不正确。这是因为我对模板很陌生,不知道如何有效地利用它们。我现在发布的解决方案是一个有效的解决方案:

//IObserver.hpp
#pragma once
#include <memory>
template <class T>
class IObserver
{
public:
    virtual ~IObserver() {};
    virtual void Notify(T data) = 0;
protected:
};

//Observable.hpp
#pragma once
#include "IObserver.hpp"
#include <list>
#include <string>
#include <memory>
template<class T>
class Observable
{
public:
    void NotifyObservers(T data)
    {
        for (auto o : m_observers)
        {
            o.Notify(data);
        }
    }
    void AddObserver(std::shared_ptr<IObserver<T>> &obs)
    {
        m_observers.push_back(obs);
    }
    void RemoveObserver(std::shared_ptr<IObserver<T>> &obs)
    {
        m_observers.remove(obs);
    }
private:
    std::list<std::shared_ptr<IObserver<T>>> m_observers;
};