C++ 使 shared_ptr 不使用删除

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/441306/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:22:29  来源:igfitidea点击:

make shared_ptr not use delete

c++boost

提问by Greg Domjan

in my code i would like boost::shared_ptr not to call delete but call ptr->deleteMe() instead.

在我的代码中,我希望 boost::shared_ptr 不调用 delete 而是调用 ptr->deleteMe() 。

Also i have a few C styled functions that return a ptr. Can i make it call lib_freeXYZ(ptr); instead of trying to delete?

我也有一些 C 风格的函数返回一个 ptr。我可以让它调用 lib_freeXYZ(ptr); 而不是试图删除?

回答by Greg Domjan

Or how about using the stl to provide the wrapper functor - Doug T. description but without the custom caller.

或者如何使用 stl 提供包装函子 - Doug T. 描述但没有自定义调用者。

boost::shared_ptr<T> ptr( new T, std::mem_fun_ref(&T::deleteMe) );
boost::shared_ptr<S> ptr( new S, std::ptr_fun(lib_freeXYZ) );

回答by Doug T.

You can give the shared_ptr template a custom deleter function which has the signature

您可以为 shared_ptr 模板提供具有签​​名的自定义删除器函数

  void Deleter( T* ptr);

for a boost::shared_ptr

对于 boost::shared_ptr

So for Deleter you would do

所以对于 Deleter 你会做

  boost::shared_ptr<T> ptrToT( new T, Deleter );

then in the body of Deleter:

然后在 Deleter 的正文中:

   void Deleter( T* ptr);
   {
        ptr->deleteMe();
        // And make sure YOU ACTUALLY DELETE (or do whatever else you need to
        // do to release the resource)
        delete ptr;
   }

For your specific case when you need something simple (like ptr->deleteMe) see Greg's solution, its very nice.

对于您需要简单操作(如 ptr->deleteMe)的特定情况,请参阅 Greg 的解决方案,它非常好。

回答by Johannes Schaub - litb

Doug T.answered your question nicely. I'll tell you about intrusive_ptr. Maybe you can use it in your project too.

Doug T.很好地回答了你的问题。我会告诉你关于 intrusive_ptr 的。也许你也可以在你的项目中使用它。

If you have some C library that has already reference counting, but you have to manually call those functions, you can use boost::intrusive_ptrtoo, and provide proper definitions for its add_ref and release functions. intrusive_ptr will find and call them. They are responsible to increment the reference count and decrement it, freeing the resource when necassary:

如果你有一些已经有引用计数的 C 库,但你必须手动调用这些函数,你也可以使用boost::intrusive_ptr,并为其 add_ref 和 release 函数提供适当的定义。intrusive_ptr 会找到并调用它们。他们负责增加引用计数并减少它,在必要时释放资源:

void intrusive_ptr_add_ref(foo *f) {
    lib_add_ref(f);
}

void intrusive_ptr_release(foo *f) {
    if(lib_dec_ref(f) == 0) 
        lib_free(f);
}

Then you can just create objects from raw pointers of type foo*. intrusive_ptrwill call your functions when its copied/destructed:

然后你可以从类型的原始指针创建对象foo*intrusive_ptr将在复制/销毁时调用您的函数:

intrusive_ptr<foo> f(lib_alloc());

// can wrap raw pointers too, which already may be referenced somewhere else
foo *p = get_foo_from_somewhere();
function_taking_intrusive_ptr(p);

回答by Kris Kumler

For the C-style data, do as @Doug. T suggested.

对于 C 样式数据,请按照@Doug 进行操作。T建议。

For your class, why not do cleanup in a destructor? Even if this is including deleteMe() in the destructor.

对于您的班级,为什么不在析构函数中进行清理?即使这在析构函数中包含 deleteMe() 。