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.
Update
The question has been clarified:
In that case, the solution is simply:
Done. It throws if the cast doesn't succeed.
Casting
shared_ptr
For
shared_ptr
there isstd::dynamic_pointer_cast<>
(http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast)Casting
unique_ptr
The simplest way would seem:
As the commenter rightfully points out, this may leak the object if the conversion failed. That's not very helpful.
A reason why the
dynamic_unique_ptr_cast<>
doesn't exist might be that theunique_ptr
type doesn't erase the deleter. It could be hard/impossible to choose an appropriate delete for the target pointer type.However, for simple cases, you could use something like this:
Unless you want to transfer ownership of your
std::unique_ptr<T>
, your function should take pointer or reference toT
.So signature of
Func
should be something likeFunc(DerivedSessionA*)
and then your call may look like:
Or as you seems to call it directly from a method in
BaseSession
:Simply get the stored pointer using the
std::unique_ptr<>::get()
method:that if
shared_from_this()
has that prototype: