【问题标题】:Smart pointer to wrap array returned by a library用于包装库返回的数组的智能指针
【发布时间】:2012-07-17 08:36:10
【问题描述】:

我正在运行 VC++ 2005,所以 std::unique_ptr AFAIK 不可用。我使用了一些库函数(黑匣子),它们有效地执行return new T[n],我想将结果包装在某个对象中,这意味着我不必在我的析构函数中删除它们。

大约 VC++ 2008 的标准库中是否存在任何内容?如果不是,unique_ptr 的 boost 版本会像 this answer 一样完美运行吗?

为了澄清 cmets 中的一些混淆,库函数返回一个指向动态分配数组的原始指针,我无权更改它...我需要获取该指针并将其包装在一个对象中,该对象会自动当对象超出范围时调用delete []

【问题讨论】:

  • 考虑使用std::vector<T>
  • 它是否有一个接受指向预分配内存的指针的ctor? cplusplus.com/reference/stl/vector/vector如果你能提供一个可行的例子,答案就是你的:)
  • 你可以给它一个初始大小,它是一个连续的内存块。 T 的类型是什么?
  • @hmjd:但它不适用于预分配的内存,因此除非您可以修改库本身,否则这不是一个真正的选择。
  • @luskan - 因为 STL/boost 的重点是我们不会继续制作自己的所有版本。

标签: c++ boost stl smart-pointers visual-c++-2005


【解决方案1】:

在 2011 之前的标准库中,你只有 auto_ptr,它适合从函数返回。但是,它只适用于单个对象,而不适用于数组,因此不适合这种用途。

据我所知,Boost 中没有unique_ptr。有一个scoped_ptrscoped_array,但它们是不可转移的,因此不能从函数中返回。

boost::shared_array 可能是合适的,尽管它使用引用计数,因此与单一所有权指针相比具有(希望很小)开销。

std::vector 可能是个不错的选择;只要您的编译器支持“返回值优化”,那么您就可以(稍加注意)从函数中返回一个,而无需任何不必要的内存分配或复制。但是,它的缺点是不能防止意外复制数据。

更新:我刚刚注意到您问题中的“黑匣子”一词,我认为这可能意味着库函数返回原始指针,并且您希望将它们分配给将使用 @987654329 销毁它们的智能指针@,并且不能修改函数本身。如果是这样的话,boost::scoped_array 应该做的伎俩,并向那些因为我的 cmets 删除他们的答案的人道歉。

【讨论】:

  • std::vector 仅适用于您可以更改库本身的情况,我不确定这是 OP 的情况。
  • @MatthieuM.:是的,我只是注意到我误读了这个问题。我以为他想返回一个智能指针,而不是处理返回的原始指针。
  • boost::unique_ptr 似乎存在 (boost.org/doc/libs/1_37_0/doc/html/boost/interprocess/…) 但它是否与现代 std::unique_ptr 相同我不知道。但是,如果我们使用 boost,看起来 boost::scoped_array 对于一个包含需要在类销毁时删除的数组的类成员变量来说更好。
  • @John: boost::interprocess::unique_ptr 用于在进程之间共享内存(位于interprocess 命名空间中)。我不知道它是否适合管理普通内存,看起来你必须提供自己的删除器来处理数组,不像std::unique_ptr 专门用于数组。 scoped_array 听起来更合适,尤其是在您不需要转让所有权的情况下。
【解决方案2】:

这取决于你想对结果值做什么。

一般来说,我建议在 C++03 中使用 boost::scoped_ptrboost::scoped_array。但是请注意,它们是用一种非常具体的思维方式制作的:限制资源的范围。也就是说,它们不仅仅是处理清理,它们还保证资源不会离开作用域,即不能转移给调用者。

如果你想要更多,这在 C++03 中并不容易(因为没有可移动类型)。在这种情况下,您可能需要制作一个“扩展”boost::scoped_ptr,例如添加一个 release 方法以允许将内存传递给调用者(然后期望正确处理它)。

【讨论】:

    猜你喜欢
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 2021-10-13
    相关资源
    最近更新 更多