I have a class provided from a library like so:
template <typename T>
class TypedClass
{
public:
typedef typename boost::shared_ptr<TypedClass<T> > Ptr;
T m_data;
T* m_pointer_data;
};
Assuming I'm willing to accept that int and float are always the same size (and alignment) on this particular architecture, this seems valid to me:
TypedClass<int>* int_object = new TypedClass<int>();
TypedClass<float>* float_object = reinterpret_cast<TypedClass<float>* >(int_object);
Now I'm trying to achieve the same thing using boost shared_ptrs and have come up with this:
TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());
void* int_object_void_pointer = reinterpret_cast<void*>(int_object.get());
TypedClass<float>::Ptr float_object(reinterpret_cast<TypedClass<float>*>(int_object_void_pointer));
Which appears to work fine, but this use of shared pointers will cause the object to be deleted twice which I'd like to avoid.
Important to note that 'TypedClass' is part of a third-party library and that this library uses shared pointers for all it's internal functionality, so I need the data in this form. I have previously solved this problem inheriting from boost enable_shared_from_this, but that's not possible here.
This is a just a simple technique to attempt to reuse the same object for data types that have the same size without having to allocate a new object with the new type.
Suggestions welcome.
shared_ptr<T>
has an interesting overloaded constructor:
template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p);
Basically this constructs a shared_ptr which takes the deleter and the refcounting from r
, except that it holds p
.
You can use it like this:
TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());
TypedClass<float>::Ptr float_object(int_object,reinterpret_cast<TypedClass<float>*>(int_object.get()));
EDIT:
If you are using Boost >= 1.53.0, there is also boost::reinterpret_pointer_cast
. So you can write:
TypedClass<float>::Ptr float_object = boost::reinterpret_pointer_cast<TypedClass<float> >(int_object);