2
votes

I am implementing a shared_pointer template that holds a pointer to typename T I want to implement a copy-constructor (with a pointer of a Base class (T)) that receives a shared pointer class (that holds a pointer to a Derived class(O)). How can i cast the received pointer to shared_ptr from Base type?

template <typename T>
class Shared_Ptr
{
public:
    template <typename O>friend class Shared_Ptr;    
    template <typename O>
    Shared_Ptr(const Shared_Ptr<O>& other_);
private:
    struct PtrVal
    {
        PtrVal(T* ptr);
        ~PtrVal();
        T *m_ptr;
        size_t m_count;
    };

    PtrVal *m_val;  
};

How can I implement the Copy-Constructor??

template <typename T>
template <typename O>
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_): 
m_val(static_cast<const Shared_Ptr<T> >(other_).m_val)
{}

This compiles but gives Segmentation fault (core dumped) at run time.

I've found another solution but it is really ugly: I convert m_ptr of other_ to T* (instead of O*) and then cast m_val of O to m_val of T

Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_)
{
    if(dynamic_cast<T *>(other_.m_val->m_ptr))
    {}

    m_val = (Shared_Ptr<T>::PtrVal *)other_.m_val;
}

Any suggestions to something better? Thank you

1
have a look in the source code for boost::shared_ptr and std::shared_ptr. You'll see that the deleter is also stored in the control block (which is important for type-erasure).Richard Hodges
You should be more accurate with terminology, what you call copy ctor is not one.Slava

1 Answers

1
votes

You want to cast m_ptr, not other_ because Shared_Ptr<O> and Shared_Ptr<T> have no inheritance relationship.

template <typename T>
template <typename O>
Shared_Ptr<T>::Shared_Ptr(const Shared_Ptr<O>& other_):
    m_val (static_cast<T*>(other_.m_val->m_ptr))
{}

You will also have to update the counter.