Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent delete px.get() for a unique_ptr

Tags:

c++

c++11

On the boost.org website, I saw an example of preventing delete px.get() for a 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 this using std::unique_ptr in C++11, and after tooling around for a bit, I can't quite get their example working with std::unique_ptr.

Is it possible to prevent delete px.get() from being called on a std::unique_ptr?

Here is the code from the boost.org website showing how to prevent delete px.get from being called:

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;
    }
};
like image 542
AhiyaHiya Avatar asked Sep 27 '12 15:09

AhiyaHiya


1 Answers

The idea remains the same for unique_ptr also, except for the fact that the type of the deleter is part of the unique_ptr's 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 conversion of capture-less lambda to a function pointer, so the first create_unique will not work on it.

like image 109
Praetorian Avatar answered Sep 29 '22 03:09

Praetorian