We all know that we can easily convert unique_ptr to shared_ptr in C++. But what if I have made such a conversion :-
unique_ptr<X> u=make_unique<X>(); // X is some class
shared_ptr<X> s=move(u); // this works of course
And now i want to transfer the ownership of the pointer in s
back to u
. Sadly there is no release() function in shared_ptr like in unique_ptr
else I could have dont something like this :-
u.reset(s.release());
Moreover this also fails to work :-
u.reset(s.get());
Can anyone suggest me how to convert shared_ptr
to unique_ptr
or atleast release the pointer owned by shared_ptr
?
As everyone has mentioned, you cannot convert shared_ptr
to unique_ptr
because more than one shared_ptr
might be owning the object. Hence there is no release() function
for shared_ptr
. Had there been one & you would have used release()
on one shared_ptr
object when more than one of such would be sharing a resource then there would be ambiguity for other shared_ptr
pointers as to whether they own the resource or not.
However, because your actual problem was regarding the static& dynamic casting
of unique_ptr
(as you have mentioned in your comments) so I would like to add that you needn't actually use shared_ptr
for casting unique_ptr
& here I show you how you can do so very simply :-
void dynamic_unique_cast (unique_ptr<Parent> &pa)
{
unique_ptr<Child> pb;
Parent *p=pa.release(); // release ownership
try
{
pb.reset(dynamic_cast<Child*>(p)); // perform casting
if (pb==nullptr)
throw runtime_error {"nullptr exception"};
cout<<"dynamic_cast successful\n\n";
pa.reset(pb.release()); // if casting is successful then `pb` returns ownership back to `pa`
}
catch (exception &e)
{
cout<<"dynamic_cast unsuccessful: "<<e.what()<<"\n\n";
pa.reset(p); // if casting fails then `p` returns ownership to `pa`
}
}
void static_unique_cast (unique_ptr<Parent> &pa)
{
unique_ptr<Child> pb;
Parent *p=pa.release();
try
{
pb.reset(static_cast<Child*>(p));
if (pb==nullptr)
throw runtime_error {"nullptr exception"};
show(pb);
cout<<"static_cast successful\n\n";
pa.reset(pb.release());
}
catch (exception &e)
{
cout<<"static_cast unsuccessful: "<<e.what()<<"\n\n";
pa.reset(p);
}
}
The above code works pretty well & will definitely solve your problem. If you have any ambiguity then feel free to comment.