7

boost.org Webサイトで、shared_ptrのdelete px.get()を防止する例を見ました(http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/sp_techniques.html#preventing_delete)。

これは優れた手法であり、C++11でstd::unique_ptrを使用してこれを適用したいと思います。少しツールを使用した後、std::unique_ptrでの例を完全に機能させることはできません。

削除px.get()がstd :: unique_ptrで呼び出されないようにすることは可能ですか?

削除px.getが呼び出されないようにする方法を示すboost.orgWebサイトのコードは次のとおりです。

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;
    }
};
4

2 に答える 2

2

unique_ptr削除者のタイプがのタイプの一部であるという事実を除いて、考え方は同じですunique_ptr

#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は、キャプチャレスラムダから関数ポインターへの暗黙的な変換を実装していないため、最初のラムダは機能しcreate_uniqueません。

于 2012-09-27T15:57:52.527 に答える
2

電話をかけるdelete px.get()のはかなり愚かなことですが、偶然に簡単にできることではないため、通常は防止しようとはしません。とはいえ、unique_ptr を使用してこれを修正する方法は次のとおりですが、deleter の型が unique_ptr の型に漏れているため、醜いです (なぜそうなのかは、unique_ptr と shared_ptr の実装の詳細を調べると明らかになります)。つまり、誰でもデリータを使用できるため、ソリューションは防水でさえありません。デリーターのコンストラクターを非公開にし、X をそれのフレンドにしない限り、しかし、自分自身に尋ねなければならない質問は、なぜわざわざするのかということです。問題になるためには、誰かが意図的に書くことによって間違ったことをしなければなりませんdelete px.get()

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;
    }
};
于 2012-09-27T15:43:42.243 に答える