Detach a pointer from a shared_ptr? [duplicate]
Solution 1:
What you're looking for is a release
function; shared_ptr
doesn't have a release function. Per the Boost manual:
Q. Why doesn't shared_ptr provide a release() function?
A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.
Consider:
shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.
Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.
Two options you might consider:
- You could use
std::tr1::shared_ptr
, which would require your users to use a C++ library implementation supporting TR1 or to use Boost; at least this would give them the option between the two. - You could implement your own
boost::shared_ptr
-like shared pointer and use that on your external interfaces.
You might also look at the discussion at this question about using boost::shared_ptr in a library's public interface.
Solution 2:
there's always a way :-)
There is indeed a reason why they don't provide a release() method, but it's not impossible to create one. Make your own deleter. Something on the line of (haven't actually compiled the code, but this is the general notion):
template <typename T>
class release_deleter{
public:
release_deleter() : released_(new some_atomic_bool(false)){}
void release() {released_->set(true);}
void operator()(T* ptr){if(!released_->get()) delete ptr;}
private:
shared_ptr<some_atomic_bool> released_;
}
..
shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>());
..
release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr);
deleter->release();
some_type* released_ptr = ptr.get();