升压信号2将插槽传递到成员功能以断开连接
Boost Signals2 pass Slot to member Function for Disconnecting
我有以下使用简单boost::Signals2::Signal
的类:
class Button {
using OnClick = signal<void()>;
public:
using OnClickSlotType = OnClick::slot_type;
boost::signals2::connection add_handler(const OnClickSlotType& slot) {
return click.connect(slot);
}
void remove_handler(const OnClickSlotType& slot) {
std::cout << "Disconnectn";
click.disconnect(&slot);
}
signal<void()> click;
};
我使用如下所示的类:
void demo() { std::cout << "Demo calledn"; }
void second() { std::cout << "Secondn"; }
int main() {
Button btn;
btn.add_handler(&demo);
btn.add_handler(&second);
btn.click();
btn.remove_handler(&demo);
btn.click();
}
但功能demo
并未断开连接。输出始终为:
Demo called
Second
Disconnect
Demo called
Second
如何正确断开功能与信号的连接?
您可以多次注册同一函数,从而导致多个连接。
因此,该函数的标识不足。
相反,您可以使用connection
对象断开特定连接:
住在科里鲁
auto d = btn.add_handler(&demo);
btn.add_handler(&second);
btn.click();
d.disconnect();
btn.click();
指纹
Demo called
Second
Disconnect doesn't require access to either source or subscriber
Second
这样做的美妙之处在于它将来源、订阅者和连接分离。您可以有一个连接表并断开它们,而无需知道所涉及的各方。
奖励:scoped_connection
作用域连接是连接的 RAII 包装器。这意味着您可以以与包装器的生命周期相关联的异常安全方式断开连接。这对于防止终身问题非常有用:
住在科里鲁
#include <boost/signals2/signal.hpp>
#include <iostream>
#include <optional>
using boost::signals2::signal;
class Button {
using OnClick = signal<void(std::string const&)>;
public:
using OnClickSlotType = OnClick::slot_type;
boost::signals2::connection add_handler(const OnClickSlotType& slot) {
return click.connect(slot);
}
OnClick click;
};
struct Demo {
Demo(Button& btn, std::string name)
: _connection(btn.add_handler(std::ref(*this))),
_name(std::move(name))
{ }
Demo(Demo const&) = delete;
Demo(Demo&&) = delete;
void operator()(std::string const& msg) const {
std::cout << _name << " called (" << msg << ")n";
}
private:
boost::signals2::scoped_connection _connection;
std::string _name;
};
int main() {
Button btn;
std::optional<Demo> foo;
{
Demo bar(btn, "bar");
btn.click("first click L:" + std::to_string(__LINE__));
foo.emplace(btn, "foo");
btn.click("second click L:" + std::to_string(__LINE__));
foo.reset();
btn.click("third click L:" + std::to_string(__LINE__));
} // bar is disconnecteded
// no connections left
btn.click("last click L:" + std::to_string(__LINE__));
}
指纹
bar called (first click L:42)
bar called (second click L:46)
foo called (second click L:46)
bar called (third click L:50)
相关文章:
- 类模板的成员功能的定义在单独的TU中完全专业化
- 升压信号2将插槽传递到成员功能以断开连接
- 多次实现成员功能
- 私有成员数据不可用于公共成员功能
- 如何避免大多数成员功能相同的代码重复
- C 成员功能
- =删除用户定义的成员功能,除了构造函数,分配运算符C 11
- C 朋友课程和朋友成员功能
- C 函数调用包装器包含类成员功能作为模板参数
- 创建类成员功能
- 成员功能C 的不同实现
- 返回类型不可知模板类成员功能
- C 11螺纹 - 非静态成员功能的使用无效 - 工作GCC 5.1.0损坏的GCC 7.3.1
- 超载类成员功能标记为const
- C 功能指针和成员功能指针
- 将非静态成员函数C 的使用无效,而将成员功能作为函数变量
- 我可以使用Priority_queue的基础容器的成员功能
- 如何子类可运行任何成员功能
- 共享类时如何隐藏成员功能文件
- 从C文件访问C 类成员功能