我有一个由shared_ptr
s和weak_ptr
组成的对象结构,以避免圆度。 原始指针是禁止的,因为boost::serialization
需要在通过对象跟踪反序列化作为序列化时间时恢复共享和弱指针。物体寿命模式很复杂(粒子模拟),但完全可以预测。每当我使用weak_ptr::lock()
时,我确信指针仍然有效。通常,我使用lock().get()
,因为我只需要很短的时间。
现在,lock().get()
具有性能影响,因为它将增加共享计数(在lock()
中),然后在不久之后递减它(临时shared_ptr
被破坏)。
2002年的boost.devel post表示在开发weak_ptr
时,会考虑直接访问原始指针的功能(命名为unsafe_get
或leak
)但从来没有实现过。它的缺席迫使程序员在给定条件下使用次优接口。
现在,问题是如何模仿unsafe_get
/ leak
,换句话说,从weak_ptr
获取原始指针,对程序员的风险无效,仅阅读(不写)数据。我可以想象一些技巧,比如找出shared_ptr
内的原始指针的偏移量就可以完成这项工作。
我正在使用boost::shared_ptr
,但该解决方案也适用于c ++ 11' std::shared_ptr
。
答案 0 :(得分:5)
因为你要求便携式黑客攻击。
在boost's weak_ptr.hpp中找到的有趣代码部分是:
template<class T> class weak_ptr
{
...
public:
...
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private:
template<class Y> friend class weak_ptr;
template<class Y> friend class shared_ptr;
#endif
element_type * px; // contained pointer
boost::detail::weak_count pn; // reference counter
}; // weak_ptr
这意味着如果使用BOOST_NO_MEMBER_TEMPLATE_FRIENDS
选项编译boost,您将公开访问weak_ptr的成员px
,该成员似乎是元素类型的原始指针。
答案 1 :(得分:3)
我建议您只需同时使用weak_ptr
和原始指针,并在知道安全时直接使用原始指针作为优化。如果您愿意,可以将weak_ptr
和关联的原始指针包装在具有unsafe_get
的类中。