如何使std::shared_ptr不调用delete()

How do you make std::shared_ptr not call delete()

本文关键字:delete 调用 何使 std shared ptr      更新时间:2023-10-16

我有一些函数将std::shared_ptr作为参数,所以我被迫使用std::shared_ptr,但我传递给函数的对象不是动态分配的。如何将对象包装在std::shared_ptr中,并让std::shared_ptr不对其调用delete。

MyType t;
nasty_function(std::shared_ptr<MyType>(&t, [](MyType*){}));

在创建共享指针时指定一个无操作删除程序。例如:

void null_deleter(MyType *) {}
int main()
{
  MyType t;
  nasty_function(std::shared_ptr<MyType>(&t, &null_deleter));
}

最好的方法是使用别名构造函数:

nasty_function(std::shared_ptr<MyType>(std::shared_ptr<MyType>{}, &t));

与null deleter方法相比,这不需要分配控制块,并且是noexcept

正如@Casey和@Nevin所指出的,只有当你确信函数不会试图获得共享所有权,或者对象的寿命比可能"拥有"它的所有对象都长时,才应该这样做。

Boost.Core正是为此目的提供了一个null_deleter函数对象。

引用文件:

<boost/core/null_deleter.hpp>定义了boost::null_deleter函数对象,它可以用作具有智能指针(如unique_ptrshared_ptr)的删除器。deleter不会对解除分配时提供的指针执行任何操作,这使得在其他地方解除分配指向的对象时非常有用。

文档示例:

std::shared_ptr< std::ostream > make_stream()
{
    return std::shared_ptr< std::ostream >(&std::cout, boost::null_deleter());
}

你可以这样做:

A a;
shared_ptr<A> pa(&a);
foo(pa);
new (&pa) shared_ptr<A>();  // pa "forgets" about a

我刚刚在寻找解决方案,看到了这个问题。什么都没发现,做了一个很棒的这是我的代码

class HBitmap : public shared_ptr<HBITMAP__>
{
public:
    HBitmap();
    HBitmap(HBITMAP Handle);
    bool autoDelete = true;
};
Win32::HBitmap::HBitmap(HBITMAP Handle)
: shared_ptr<HBITMAP__>(Handle, [&](HBITMAP hBitmap)  {if(autoDelete)DeleteObject(hBitmap);})
{
}

这个解决方案是lambda表达式和继承的组合。形状非常好。快速的你不能再期待什么了。不仅可以设置deleter,而且如果进行了一些修改,可以使用std::function<void(pointer)>作为自定义deleter。有了lambdas,你可以自由奔跑,做任何你想做的事。