Search code examples
c++boostsmart-pointersunique-ptrdynamic-cast

How to perform a dynamic_cast with a unique_ptr?


I have a class hierarchy as follows:

class BaseSession : public boost::enable_shared_from_this<BaseSession>
class DerivedSessionA : public BaseSession
class DerivedSessionB : public BaseSession

Within the derived class functions, I regularly call functions like this:

Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));

Since I was working with shared_ptr to manage the sessions, this was working fine. Recently, I discovered that my use of shared_ptr is not optimal for this case. That is because these sessions are singleton objects that maintain one socket per client. If socket is reconnected, the session copies used to become zombies.

As workaround, I started passing shared_ptr by reference rather than copies. This solved the zombie problem.

Ideally, I felt I should be using unique_ptr to store the session and then pass references to other functions. That opened a whole can of worms.

How do I cast a base class unique_ptr object to derived class unique_ptr object? What is the unique_ptr version of the following line?

Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));

I just want one copy of the session object, everything else should be reference.


Solution

  • Unless you want to transfer ownership of your std::unique_ptr<T>, your function should take pointer or reference to T.

    So signature of Func should be something like Func(DerivedSessionA*)

    and then your call may look like:

    std::unique_ptr<BaseSession> ptr; // Initialize it with correct value
    
    Func(dynamic_cast<DerivedSessionA*>(ptr.get()));
    

    Or as you seems to call it directly from a method in BaseSession:

    Func(dynamic_cast<DerivedSessionA*>(this));