如何使std::shared_ptr不调用delete()
How do you make std::shared_ptr not call delete()
我有一些函数将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_ptr
或shared_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,你可以自由奔跑,做任何你想做的事。
相关文章:
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 析构函数是否会自动调用 delete[] C++?
- 调用delete[]时,某些东西导致堆损坏,但我已正确设置了数组的维度
- 在析构函数中调用"delete"运算符时"compiler is out of heap space"编译器错误
- 为什么 delete[] 不等同于 C++ 中为每个元素调用 delete?
- 有没有办法拥有一个未初始化的类数组,这些类在调用 delete[] 时不会被破坏?
- 大小运算符 delete[] 永远不会被调用
- 为什么当我在同一内存中各有两个指针时,我必须调用"delete"两次?
- c++ 运算符 new[]/delete [] 是否调用运算符 new/delete?
- 在C 中调用delete []内部破坏者
- C++17标准对在nullptr上调用delete有何规定
- 对不完整类型的空指针调用delete合法吗
- 每当在C++中调用 delete/delete[] 时都会中断调试器
- 在不同的编译器版本中调用new[]和delete[]
- WT C 如何为分配的对象调用DELETE
- 将复制构造函数超载与DELETE,然后调用C 子类的默认构造函数
- 复制指针,然后调用 delete
- delete[]调用析构函数时出现内存错误
- 使用delete调用析构函数