I am referring to a follow-up question to "Downcasting" unique_ptr<Base> to unique_ptr<Derived> which seems to make sense to me in itself.
OP asks for getting a unique_ptr<Derived>
out of a unique_ptr<Base>
, where the latter object is of dynamic type Derived
, so that the static downcast would be safe.
Normally, (as 95% of solutions in the Internet suggest, roughly estimated), the simple solution would be:
unique_ptr<Derived> ptr(static_cast<Derived*>(baseClassUniquePtr.release()));
OP also states, though
PS. There is an added complication in that some of the factories reside in DLLs that are dynamically loaded at run-time, which means I need to make sure the produced objects are destroyed in the same context (heap space) as they were created. The transfer of ownership (which typically happens in another context) must then supply a deleter from the original context. But aside from having to supply / cast a deleter along with the pointer, the casting problem should be the same.
Now, the solution seems to be to get the deleter from the unique_ptr<Base>
object and pass it to the new object, which clearly results in unique_ptr<Derived, default_delete<Base>>
. But default_delete
is stateless anyways. The only difference is the template argument. But since we always declare dtor
virtual
when using inheritance with dynamic polymorphism in C++, we always call ~Derived
anyways, so I would think, the original deleter would be safe anyways, allowing for a clean cast to unique_ptr<Derived>
(without unhandy second template argument which forbids any usual storage).
So, while I understand that we have two heap spaces when using a library (DLL, .dylib, ...) that creates an object and passes it to some executable, I do not understand how copying/moving a stateless deleter from the old object solves this issue.
Does it even solve the issue? If yes, how? If not, how can we solve this issue?
--- Edit: Also... get_deleter
returns a reference to an object lying in the old unique_ptr
which is destroyed when this old unique_ptr
is destroyed, is it not? --- (stupid question because unique_ptr
along with deleter is clearly moved)