C ++的可观察容器

问题描述 投票:6回答:5

是否有C ++容器类的实现,它以类似于C#的ObservableCollection的方式支持通知?

c++
5个回答
8
投票

没有像你描述的标准类,但Boost.Signals是一个非常强大的通知库。我会为对象创建一个包装器,当它被改变时会引发一个信号,沿着这条线:

#include <boost/signals.hpp>
#include <vector>
#include <iostream>

// Wrapper to allow notification when an object is modified.
template <typename Type>
class Observable
{
public:
    // Instantiate one of these to allow modification.
    // The observers will be notified when this is destroyed after the modification.
    class Transaction
    {
    public:
        explicit Transaction(Observable& parent) : 
            object(parent.object), parent(parent) {}
        ~Transaction() {parent.changed();}
        Type& object;

    private:
        Transaction(const Transaction&);    // prevent copying
        void operator=(const Transaction&); // prevent assignment

        Observable& parent;
    };

    // Connect an observer to this object.
    template <typename Slot>
    void Connect(const Slot& slot) {changed.connect(slot);}

    // Read-only access to the object.
    const Type& Get() const {return object;}

private:
    boost::signal<void()> changed;
    Type object;
};

// Usage example
void callback() {std::cout << "Changed\n";}

int main()
{
    typedef std::vector<int> Vector;

    Observable<Vector> o;
    o.Connect(callback);

    {
        Observable<Vector>::Transaction t(o);
        t.object.push_back(1);
        t.object.push_back(2);
    } // callback called here
}

0
投票

STL中没有这样的东西。这并不意味着某人没有在开源库中创建这样的东西,但我不相信它是该语言的一部分。


0
投票

我正在做的方式我在我的收藏中有类似notify_updatedwait_event的东西,我在更改后调用notify_updated,然后在其他部分我等待事件。我的解决方案非常特定于我正在解决的问题,所以它更像是C-ish。认为它与迈克的样本概念相似。


0
投票

这是一个开源的hpp库,只使用信号/插槽为c ++中的可观察容器提供实现(https://github.com/ricardocosme/coruja

简报:

“Coruja”在葡萄牙语中的意思是“猫头鹰”。它是使用信号和插槽的Observer模式的替代解决方案,或者是使用多态类型(如Subject和Observer)的更经典的方法。它是一个C ++ 11库,具有比Observer模式更高级别的抽象,避免了bolierplate代码和控制IoC的反转。像std :: vector这样的STL容器适合于成为可观察的容器,即,当插入或擦除元素时可以通知观察者。实际上,可以观察到范围,并且观察者可以观察例如容器的变换。可观察的容器

coruja::vector<string> v{"John Jones", "Robert Plant"};

v.for_each([](auto& member){ cout << member << endl; });

v.emplace_back("Jimmy Page");

//outputs:
//John Jones
//Robert Plant
//Jimmy Page

Observable ranges

struct person_t { std::string first_name, surname; };

vector<person_t> persons;

auto fullnames = transform
    (persons, [](auto& person){ return person.first_name + person.surname; });

fullnames.for_each([](auto&& fullname){ cout << fullname << endl; });

//outputs:
//JohnBonham
//JimmyPage

Observable objects

object<string> first_name, surname;

auto fullname = first_name + surname;
fullname.after_change([](auto&& s){ cout << s << endl; });

first_name = "Jimmy";
//outputs:
//Jimmy

surname = "Page";

//outputs:
//JimmyPage

该库根据Boost软件许可证1.0版进行分发。


-1
投票

您需要自己编写,然后将其备份到您最喜欢的容器中。

© www.soinside.com 2019 - 2024. All rights reserved.