在boost.org网站上,我看到了一个阻止删除px.get()for shared_ptr(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。< / p>
是否可以阻止在std :: unique_ptr上调用删除px.get()?
以下是来自boost.org网站的代码,其中显示了如何防止删除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;
}
};
答案 0 :(得分: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;
}
};
答案 1 :(得分: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没有实现无捕获lambda到函数指针的隐式转换,因此第一个create_unique
将不起作用。