如何使用仿函数将boost信号2与类的方法断开连接?
问题描述:
我从boost :: signals2中断开一个插槽(这是一个类方法)时,我没有看到我期待的行为。我的术语很可能是关闭的,所以我将提供一个最低工作示例(MWE),以展示我所看到的和我期望的内容。简短的版本是我断开了信号,但它停留在那里。如果我使用独立函数做到这一点,那么所有的工作都很好,当我使用一个我遇到这种行为的类方法时。如何使用仿函数将boost信号2与类的方法断开连接?
任何帮助将不胜感激!
>> 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;
}
>> 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.
>> ./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
答
使用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.
我喜欢的作用域连接的scoped_connection,但我希望不必在我的完整实施中管理另一个对象。仿函数对象已经被创建,并且将它理想地用于断开连接。如果没有其他人可以提供关于如何使用仿函数来断开连接的指导,我会接受这个答案,因为“你不能那样做,而是这样做。” –
@ KennethE.Bellock还有另外一个选项 - signals2为您提供了使用'connect_extended'的机会,这会导致对连接的引用传递给插槽处理程序。 http://www.boost.org/doc/libs/1_61_0/libs/signals2/example/extended_slot.cpp –