7

在 boost.org 网站上,我看到了一个阻止对 shared_ptr 删除 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 一起使用。

是否可以防止在 std::unique_ptr 上调用 delete px.get() ?

这是 boost.org 网站上的代码,展示了如何防止 delete 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;
    }
};
4

2 回答 2

2

虽然打电话delete px.get()是一件非常愚蠢的事情,但通常不是你试图阻止的事情,因为它不是你可以轻易做到的事情。也就是说,这是使用 unique_ptr 解决此问题的方法,但是它很丑陋,因为删除器的类型泄漏到了 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 回答
2

除了删除器的类型是's 类型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 没有实现无捕获的 lambda 到函数指针的隐式转换,所以第一个create_unique将不起作用。

于 2012-09-27T15:57:52.527 回答