![](/img/trans.png)
[英]Error: “cannot access private member declared in class 'boost::signals2::scoped_connection'”?
[英]Is it safe to use a boost::signals2::scoped_connection object as member of a class for automatic connection lifetime?
我想知道以下代碼是否安全,因為信號可能由不同的線程觸發:
using IntSignal = boost::signals2::signal<void(int)>;
class Foo
{
public:
Foo(IntSignal& signal)
: some_resource(new int(0))
{
scoped_connection = signal.connect([this](int i) { some_action(i); });
}
~Foo()
{
delete some_resource;
}
private:
void some_action(int i)
{
*some_resource = i;
}
int* some_resource;
boost::signals2::scoped_connection scoped_connection;
}
編輯:為some_action
添加了一個虛構的資源、析構函數和一個實現,以使其更加清晰。 有了這個問題,我想澄清一下我的假設是否正確,即信號槽可能在Foo
的析構函數之后但在scoped_connection
的析構函數之前調用。 為簡潔起見,我省略了保護some_resource
的互斥鎖,但是,它與問題無關。
盡管Foo
實例被銷毀時連接將被斷開,但在Foo
自己的析構函數調用和Foo
成員的銷毀之間可能存在微小的差距。 如果資源被破壞后在some_action
中使用,這可能會更成問題。
我應該使用普通連接並在Foo
的析構函數中斷開它們嗎? 將scoped_connection
成員作為 class 的最后一個成員(應該首先被銷毀)並省略任何銷毀邏輯是否安全?
你是對的,如果在信號運行和訪問some_resource
時調用Foo
的析構函數,則可能存在競爭。
一個安全的解決方案是在插槽運行時延長Foo
的壽命:
class Foo : public std::enable_shared_from_this<Foo>
{
public:
Foo(IntSignal& signal)
: some_resource(new int(0))
{
// moved connection initialization to a method since weak_from_this will
// be empty inside the constructor. It is initialized only afterwards.
// It also make sense to connect your signal only after object
// is fully initialized
}
void InitConnection()
{
auto weak_self = weak_from_this();
scoped_connection = signal.connect(
[weak_self](int i)
{
if (auto self = weak_self.lock())
{
// we managed to promote weak_self to a shared_ptr, 'this' will be alive
// as long as this scope lives
some_action(i); // safe
}
});
}
~Foo()
{
// will only be invoked after Foo's reference count drops to zero.
// not during the signal is emitted
delete some_resource;
}
private:
void some_action(int i)
{
*some_resource = i;
}
int* some_resource;
boost::signals2::scoped_connection scoped_connection;
}
筆記:
enable_shared_from_this
將weak_ptr
初始化為“this”。 對於您描述的情況,這是一個很好的工具。 在這里查看更多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.