gpt4 book ai didi

c++ - 强制删除 boost::signals2 中的插槽

转载 作者:IT老高 更新时间:2023-10-28 23:19:41 25 4
gpt4 key购买 nike

我发现 boost::signals2 使用了一种对连接槽的延迟删除,这使得很难将连接用作管理对象生命周期的东西。我正在寻找一种方法来强制在断开连接时直接删除插槽。任何关于如何通过不同地设计我的代码来解决问题的想法也很感激!

这是我的场景:我有一个 Command 类负责异步执行需要时间的操作,看起来像这样(简化):

class ActualWorker {
public:
boost::signals2<void ()> OnWorkComplete;
};

class Command : boost::enable_shared_from_this<Command> {
public:
...

void Execute() {
m_WorkerConnection = m_MyWorker.OnWorkDone.connect(boost::bind(&Command::Handle_OnWorkComplete, shared_from_this());

// launch asynchronous work here and return
}

boost::signals2<void ()> OnComplete;

private:
void Handle_OnWorkComplete() {
// get a shared_ptr to ourselves to make sure that we live through
// this function but don't keep ourselves alive if an exception occurs.
shared_ptr<Command> me = shared_from_this();

// Disconnect from the signal, ideally deleting the slot object
m_WorkerConnection.disconnect();

OnComplete();

// the shared_ptr now goes out of scope, ideally deleting this
}

ActualWorker m_MyWorker;
boost::signals2::connection m_WorkerConnection;
};

这个类是这样调用的:

...
boost::shared_ptr<Command> cmd(new Command);
cmd->OnComplete.connect( foo );
cmd->Execute();
// now go do something else, forget all about the cmd variable etcetera.

Command 类通过为自身获取一个 shared_ptr 来保持自身事件,该 shared_ptr 使用 boost::bind 绑定(bind)到 ActualWorker 信号。

当工作人员完成时,会调用 Command 中的处理程序。现在,由于我希望销毁 Command 对象,因此我断开了与信号的连接,如上面的代码所示。问题是实际的槽对象在断开连接时并没有被删除,它只是被标记为无效,然后在以后删除。这反过来似乎取决于再次触发的信号,在我的情况下它没有这样做,导致插槽永不过期。因此 boost::bind 对象永远不会超出范围,它会为我的对象保存一个永远不会被删除的 shared_ptr。

我可以通过使用 this 指针而不是 shared_ptr 进行绑定(bind)来解决这个问题,然后使用成员 shared_ptr 保持我的对象事件,然后我在处理函数中释放它,但这有点让设计感觉有点过于复杂。有没有办法在断开连接时强制信号2删除插槽?或者我还能做些什么来简化设计?

欢迎评论!

最佳答案

boost::signals2 确实会在连接/调用期间清理插槽。

因此,如果所有槽都与信号断开连接,第二次调用信号不会调用任何东西,但它应该清理槽。

回答您的评论,是的,如果有其他插槽连接,再次调用信号是不安全的,因为它们将被再次调用。在这种情况下,我建议您反过来连接一个虚拟插槽,然后在调用“真实”插槽时断开它。连接另一个插槽将清除陈旧的连接,因此您的插槽应该被释放。

只要确保您没有在虚拟插槽中保留任何需要释放的引用,否则您会回到开始的位置。

关于c++ - 强制删除 boost::signals2 中的插槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2049291/

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