c++ - 如何以及为什么要使用 Boost 信号2?

标签 c++ events boost boost-signals2

学习 c++ 并尝试熟悉一些模式。 signals2 doc显然,我可以用插槽和信号做很多事情。我不明白我应该将它用于什么类型的应用程序(用例)。

我正在按照状态机调度更改事件的思路进行思考。来自动态类型的背景(C#、Java 等),您将使用事件调度程序或静态引用或回调。

在 C++ 中使用跨类回调有困难吗?这本质上是为什么信号2存在吗?

示例案例之一是文档/ View 。这种模式比使用函数 vector 并在循环中调用每个函数,或者说在注册的监听类实例中调用状态更改的 lambda 更适合吗?

class Document
{
public:
    typedef boost::signals2::signal<void ()>  signal_t;

public:
    Document()
    {}

    /* Connect a slot to the signal which will be emitted whenever
      text is appended to the document. */
    boost::signals2::connection connect(const signal_t::slot_type &subscriber)
    {
        return m_sig.connect(subscriber);
    }

    void append(const char* s)
    {
        m_text += s;
        m_sig();
    }

    const std::string& getText() const
    {
        return m_text;
    }

private:
    signal_t    m_sig;
    std::string m_text;
};

class TextView
{
public:
    TextView(Document& doc): m_document(doc)
    {
        m_connection = m_document.connect(boost::bind(&TextView::refresh, this));
    }

    ~TextView()
    {
        m_connection.disconnect();
    }

    void refresh() const
    {
        std::cout << "TextView: " << m_document.getText() << std::endl;
    }
private:
    Document&               m_document;
    boost::signals2::connection  m_connection;
};

最佳答案

Boost.Signals2 不仅仅是“回调数组”,它还有很多附加值。 IMO,最重要的几点是:

  1. 线程安全:多个线程可以同时连接/断开/调用同一个信号,而不会引入竞争条件。这在与异步子系统通信时特别有用,例如在自己的线程中运行的事件对象。
  2. connectionscoped_connection 句柄允许在不直接访问 signal 的情况下断开连接。请注意,这是断开无法比较的插槽的唯一方法,例如 boost::function(或 std::function)。
  3. 临时插槽阻塞。提供一种临时禁用监听模块的简洁方法(例如,当用户请求暂停在 View 中接收消息时)。
  4. 自动槽生命周期跟踪:信号自动从“过期”槽断开。考虑当一个 slot 是一个 binder 引用由 shared_ptrs 管理的不可复制对象时的情况:

    shared_ptr<listener> l = listener::create();
    auto slot = bind(&listener::listen, l.get()); // we don't want aSignal_ to affect `listener` lifespan
    aSignal_.connect(your_signal_type::slot_type(slot).track(l)); // but do want to disconnect automatically when it gets destroyed
    

当然,可以“使用函数 vector 并在循环中调用每个函数”等自己重新实现上述所有功能,但问题是它如何比 Boost.Signals2。重新发明轮子并不是一个好主意。

关于c++ - 如何以及为什么要使用 Boost 信号2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18663490/

相关文章:

c++ - 模板类和派生类

javascript - 触发 iframe 上的点击不起作用

python - 具有 'externally' 更新属性的 PyTango 设备

c++ - enable_shared_from_this - 空的内部弱指针?

c++ - boost::bind 与成员函数(作为 boost::asio 异步写处理程序)

c++ - boost 认识 child

c++ - 未知类型 C++

c++ - 如何正确释放一组指针?

jquery - jquery防止点击事件

c++ - 如何在boost进程间构建vector of vector