I have object structure which is made of shared_ptr
s, plus weak_ptr
s to avoid circularity. Raw pointers are a no-go as boost::serialization
needs to restore shared and weak pointers when deserializing via object tracking as serialization time. Object lifetime patterns are complex (particle simulation) but entirely predictable. Whenever I use weak_ptr::lock()
, I am sure the pointer is still valid. Typically, I use lock().get()
as I only need the object for a very short time.
Now, lock().get()
has performance implications, as it will increment shared count (in lock()
), and then decrement it shortly afterwards (the temporary shared_ptr
is destructed).
This boost.devel post from 2002 says that while weak_ptr
was being developed, the functionality of accessing the raw pointer directly was considered (to be named unsafe_get
or leak
) but never made it to the actual implementation. Its absence forces programmer to use suboptimal interface under given conditions.
Now, the question is how to emulate the unsafe_get
/leak
, in another words, get the raw pointer from weak_ptr
, invalid at the programmer's risk, only reading (not writing) data. I can imagine that some trickery like finding out the offset of the raw pointer inside shared_ptr
or such would do the job.
I am using boost::shared_ptr
, but the solution could work for c++11's std::shared_ptr
as well.
Since you asked for a portable hack.
A funny part of code found in boost's weak_ptr.hpp is:
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
Which means if you compile boost with the BOOST_NO_MEMBER_TEMPLATE_FRIENDS
option, you will publicly have access to the member px
of weak_ptr which seems to be a raw pointer to the element type.
I suggest you simply hold both a weak_ptr
and a raw pointer and use the raw pointer directly as an optimization when you know it is safe to do so. You could wrap up the weak_ptr
and associated raw pointer in a class that has an unsafe_get
if you like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With