在C ++中实现Observer模式

时间:2014-04-18 00:14:16

标签: c++ templates stl observer-pattern

我正在用C ++编写一个非常简单的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

2 个答案:

答案 0 :(得分:0)

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

对于终身管理和识别,请使用:std::weak_pointer
对于多态函数(对象),std::function
并将它们放在一起使用std::pair

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

答案 1 :(得分:0)

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

//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;
};