![](/img/trans.png)
[英]Why doesn't std::enable_shared_from_this use a mutable std::weak_ptr?
[英]Why does enable_shared_from_this lack direct access to the embedded weak_ptr?
我想在多线程应用程序中使用带有自动连接管理功能的boost signal2。 我的课继承自enable_shared_from_this<>
,我想从另一个成员方法中连接一个成员方法。 连接可能会经常重建,因此我的代码应尽可能快(尽管boost2本身具有性能):
typedef boost::signals2::signal<void ()> signal_type;
struct Cat : public enable_shared_from_this<Cat>
{
void meow ();
void connect (signal_type& s)
{
// can't write this
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
// ok, but slow?! two temporary smart pointers
weak_ptr<Cat> const myself (shared_from_this ());
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (myself));
}
// i am missing something like this in the base class
// protected:
// weak_ptr<Cat> const& weak_from_this ();
};
我知道我的设计目标可能会冲突(自动连接管理和线程安全以及快速代码),但无论如何:
为什么enable_shared_from_this<>
无法直接访问嵌入式的weak_ptr<>
? 我看不出相反的理由。 没有像我这样的用例吗?
是否有比以上方法更快的解决方法?
编辑:
我知道我可以做这样的事情,但是我想避免额外的存储/初始化检查损失:
template <typename T>
struct enable_weak_from_this : public enable_shared_from_this<T>
{
protected:
weak_ptr<T> /* const& */ weak_from_this ()
{
if (mWeakFromThis.expired ())
{
mWeakFromThis = this->shared_from_this ();
}
return mWeakFromThis;
}
private:
weak_ptr<T> mWeakFromThis;
};
您无权访问weak_ptr
是enable_shared_from_this
不必使用一个 。 拥有weak_ptr
只是enable_shared_from_this
一种可能实现。 它不是唯一的。
由于enable_shared_from_this
与shared_ptr
是同一标准库的一部分,因此,与直接存储weak_ptr
相比,可以使用更有效的实现。 而且委员会也不想阻止这种优化。
//可以,但是慢吗? 两个临时智能指针
那只是一个临时的智能指针。 复制省略/移动应注意除第一个对象外的所有内容。
可能是因为没有引用Cat
实例的shared_ptr
。 weak_ptr
要求至少有一个活动的shared_ptr
。
尝试将shared_ptr
放置为成员变量,并首先在connect
方法中为其分配:
typedef boost::signals2::signal<void ()> signal_type;
struct Cat : public enable_shared_from_this<Cat>
{
void meow ();
boost::shared_ptr<Cat> test;
void connect (signal_type& s)
{
test = shared_from_this();
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
}
};
但基本上,如果没有shared_ptr
,就不会有weak_ptr
。 如果所有shared_ptr
disapear而weak_ptr
仍然在使用,那么weak_ptr
可以指向一个不存在的对象。
注意:我的测试不应在生产代码中使用,因为它将导致该对象永远不会被释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.