How to prevent the removal of px.get () for unique_ptr

On boost.org, I saw an example of preventing px.get () from being deleted for shared_ptr ( http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/sp_techniques.html#preventing_delete ).

This is a good technique, and I would like to apply it with std :: unique_ptr in C ++ 11, and after a small set of tools I cannot get an example with std :: unique_ptr.

Is it possible to prevent the removal of px.get () in std :: unique_ptr?

Here is the code from boost.org showing how to prevent the removal of px.get:

class X { private: ~X(); class deleter; friend class deleter; class deleter { public: void operator()(X * p) { delete p; } }; public: static shared_ptr<X> create() { shared_ptr<X> px(new X, X::deleter()); return px; } }; 
+6
source share
2 answers

The idea remains the same for unique_ptr , except for the fact that the type of deleter is part of the unique_ptr type.

 #include <functional> #include <memory> #include <iostream> using namespace std; class X { private: ~X() {} class deleter { public: void operator()(X * p) { delete p; } }; friend class deleter; public: static shared_ptr<X> create_shared() { shared_ptr<X> px(new X, X::deleter()); return px; } static unique_ptr<X, void(*)(X*)> create_unique() { return unique_ptr<X, void(*)(X*)>( new X, []( X *x ) { X::deleter()( x ); } ); } // If using VS2010 static unique_ptr<X, std::function<void(X*)>> create_unique() { return unique_ptr<X, std::function<void(X*)>>( new X, X::deleter() ); } }; int main() { auto x = X::create_shared(); auto y = X::create_unique(); } 

VS2010 does not implement implicit lambda conversion without capturing to a function pointer, so the first create_unique will not work on it.

+2
source

When you call delete px.get() this is a pretty silly thing that you usually don’t do, because it is not something that you can easily do by accident. However, here's how to fix it with unique_ptr, however it is ugly because the type of leak removal is of type unique_ptr (why it becomes clear when you look at the implementation details of unique_ptr vs. shared_ptr), and therefore Debtor should be publicly available. which means that the solution is not even waterproof, because anyone can use a deleter. Unless you create a deleter private constructor and make X its friend, however, the question you should also ask yourself is what to worry about? Someone must knowingly do the wrong delete px.get() writing delete px.get() so that it becomes a problem.

 class X { private: ~X() {} public: struct deleter { void operator()(X * p) { delete p; } }; static std::unique_ptr<X, deleter> create() { std::unique_ptr<X, deleter> px(new X, deleter()); return px; } }; 
+2
source

Source: https://habr.com/ru/post/926422/


All Articles