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 .
The ownership of an object can only be shared with another shared_ptr by copy constructing or copy assigning its value to another shared_ptr . Constructing a new shared_ptr using the raw underlying pointer owned by another shared_ptr leads to undefined behavior.
So no, you shouldn't. The purpose of shared_ptr is to manage an object that no one "person" has the right or responsibility to delete, because there could be others sharing ownership. So you shouldn't ever want to, either.
A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .
The standard library does not really facilitate such a move, going from std::unique_ptr
to std::shared_ptr
is always safe (because of the semantics of the two) — but the opposite is dangerous since there might be more owners of the resource than the particular std::shared_ptr
you would like to move from.
I should probably tell you one more time, but I will assume that you are somewhat grown up and can stand accountable for your own decisions.
If you would like to hack together a solution that would not be undefined-behavior unless the std::unique_ptr
goes out of scope and you still have std::shared_ptrs
that directly or indirectly end up using the resource.. you would probably end up with something like:
#include <memory>
namespace hack {
struct conditional_deleter {
void disable () { _do_delete = false; }
template<class T>
void operator()(T* p) {
if (_do_delete)
delete p;
}
bool _do_delete = true;
};
}
int main () {
std::unique_ptr<int> up (new int (123));
std::shared_ptr<int> sp (up.release (), hack::conditional_deleter {});
std::shared_ptr<int> sb (sp);
std::get_deleter<hack::conditional_deleter> (sp)->disable ();
std::unique_ptr<int> ub (sp.get ()); // see the name of this variable?
} // can I get a ticket to UB-land, please?
WARNING
The above is far from recommended praxis, if you ever find yourself in a situation where you need such thing you should set fire to your workstation—probably your whole house—and work on a new program design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With