【问题标题】:How do you disconnect from a boost signal2 using a functor to a method of a class?如何使用函子与类的方法断开升压信号2?
【发布时间】:2017-09-22 18:38:03
【问题描述】:

从 boost::signals2 断开插槽(即类方法)时,我没有得到预期的行为。我的术语可能是错误的,所以我将在下面提供一个最小的工作示例(MWE)来展示我所看到的和我所期望的。简短的版本是我与信号断开连接,但它一直呆在那里。如果我使用独立函数执行此操作,一切都会很好,当我使用类方法时,我会遇到这种行为。

任何帮助将不胜感激!

>> tree

.
├── main.cpp
└── SConstruct

0 directories, 2 files

>> cat SConstruct

Program('main.cpp')

>> cat main.cpp

#include <boost/signals2.hpp>
#include <iostream>
struct foo {
    void bar(int n) {
        std::cout << "Called foo::bar with " << n << std::endl;
    }
};
typedef boost::function<void(int)> Signal_f;
int main() {

    foo f;
    boost::signals2::signal< void(int) > my_signal;
    Signal_f functor = boost::bind(&foo::bar, f, _1);
    std::cout << "Created signal, and it has "
              << my_signal.num_slots() << " subscribers." << std::endl;
    my_signal.connect(functor);
    std::cout << "Subscribed to signal, and it has "
              << my_signal.num_slots() << " subsciber." << std::endl;
    my_signal(1);
    my_signal.disconnect(&functor);
    std::cout << "Un-Subscribed to signal, but it still has "
              << my_signal.num_slots()
              << " subsciber, and it should not have any now." << std::endl;
    my_signal(2);
    return 0;
}

&gt;&gt; scons

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.o -c main.cpp
g++ -o main main.o
scons: done building targets.

&gt;&gt; ./main

Created signal, and it has 0 subscribers.
Subscribed to signal, and it has 1 subsciber.
Called foo::bar with 1
Un-Subscribed to signal, but it still has 1 subsciber, and it should not have any now.
Called foo::bar with 2

【问题讨论】:

    标签: c++ boost publish-subscribe


    【解决方案1】:

    使用scoped_connection重新实现:

    #include <boost/signals2.hpp>
    #include <iostream>
    struct foo {
        void bar(int n) {
            std::cout << "Called foo::bar with " << n << std::endl;
        }
    };
    
    
    
    typedef boost::function<void(int)> Signal_f;
    int main() {
    
        using boost::signals2::scoped_connection;
    
        foo f;
        boost::signals2::signal< void(int) > my_signal;
        Signal_f functor = boost::bind(&foo::bar, f, _1);
        std::cout << "Created signal, and it has "
                  << my_signal.num_slots() << " subscribers." << std::endl;
    
        // the scoped_connection object is RAII
        auto con = scoped_connection(my_signal.connect(functor));
    
        std::cout << "Subscribed to signal, and it has "
                  << my_signal.num_slots() << " subsciber." << std::endl;
        my_signal(1);
    
        // disconnect the connection object, not the signal
        con.disconnect();
        std::cout << "Un-Subscribed to signal, and it now has "
                  << my_signal.num_slots()
                  << " subscibers." << std::endl;
        my_signal(2);
        return 0;
    }
    

    预期输出:

    Created signal, and it has 0 subscribers.
    Subscribed to signal, and it has 1 subsciber.
    Called foo::bar with 1
    Un-Subscribed to signal, and it still has 0 subscibers.
    

    【讨论】:

    • 我确实喜欢范围连接,但我希望在我的完整实现中不必管理另一个对象。函子对象已经被创建,使用它来断开连接是理想的。如果没有其他人可以提供有关如何使用函子断开连接的指导,我会接受这个答案,因为“你不能这样做,而是这样做。”
    • @KennethE.Bellock 还有另一种选择——signals2 让您有机会使用connect_extended,这会导致将对连接的引用传递给插槽处理程序。 boost.org/doc/libs/1_61_0/libs/signals2/example/…
    【解决方案2】:

    我确实使用 connect 方法返回的 boost::signals2::connection 对象与 boost::signal2::signal 断开连接。

    【讨论】:

    • 我更喜欢自动处理东西的 scoped_connection
    猜你喜欢
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多