gpt4 book ai didi

c++ - boost::signals2 仍然向引用死亡的对象发出信号

转载 作者:行者123 更新时间:2023-11-30 04:44:33 28 4
gpt4 key购买 nike

我目前正在研究信号/槽,并尝试为微 Controller 编写我自己的小库。在这种情况下,我遇到了一个错误,当我将一个对象(上下文)和一个成员函数作为槽函数传递时,尽管对象已经死了,槽仍然被调用。

考虑以下示例:

#include <boost/signals2.hpp>
#include <iostream>

struct A
{
void does() {
std::cout << "i: " << i << " addr: " << (uint64_t)&*this << std::endl;
}
int i = 0;
};


int main()
{
boost::signals2::signal<void()> sig;

{
A a;
std::cout << "addr: " << (uint64_t)&a << std::endl;
sig.connect( [&a]{a.does();});
sig();
}
{
A a;
a.i = 3;
}
sig();
}

输出:

addr: 140722327054036
i: 0 addr: 140722327054036
i: 0 addr: 140722327054036

第一次cout是正常的。通过信号发出的第二个也可以。但是第三个很奇怪。对我来说,因为第一个 a 死了,我用 i = 3 创建了第二个,通常它应该在第二个信号中打印 3 自堆栈变量应该被完全覆盖。

顺便说一句,这与我想在我的库中实现的问题相同。我想跟踪引用资料。但我认为这是不可能的,可能不会在析构函数内部引发某种信号。

那么解决这个问题的好方法是什么?我唯一能想到的就是 Pub/Sub 模式。这感觉几乎是一样的。但我有点不喜欢这样的事实,即每个可以捕获信号的类都必须由订阅者类派生。

最佳答案

您可以使用作用域连接来管理连接的生命周期。

scoped_connection keep = sig.connect([&a] { a.does(); });

参见 Live On Coliru

#include <boost/signals2.hpp>
#include <iostream>

namespace bs = boost::signals2;

static inline int genid() { static int s_current = 0; return ++s_current; }

struct A {
int i = genid();
void operator()() const { std::cout << "i: " << i << std::endl; }
};

int main() {
bs::signal<void()> sig;

{
A a;
bs::scoped_connection keep = sig.connect(a);
sig();
}
{
A a[100] = {};
}
sig();
}

只是打印

i: 1

关于c++ - boost::signals2 仍然向引用死亡的对象发出信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57707250/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com