【问题标题】:unique_ptr with an API that expects raw pointers?具有需要原始指针的 API 的 unique_ptr?
【发布时间】:2012-04-12 02:32:16
【问题描述】:

在使用托管内存和函数式语言大约 10 年之后,我终于回到了 C++ 领域,而智能指针让我很困惑。有一半的文档仍然是关于已弃用的auto_ptr

我正在尝试实现这个相当简单的 Bullet "hello world" 程序:

int _tmain(int argc, _TCHAR* argv[])
{
    auto bp = unique_ptr<btBroadphaseInterface>(new btDbvtBroadphase);
    auto cc = unique_ptr<btDefaultCollisionConfiguration>(new btDefaultCollisionConfiguration);
    auto disp = unique_ptr<btDispatcher>(new btCollisionDispatcher(cc));
}

btCollisionDispatcher 构造函数需要一个 btCollisionConfiguration*,但我将其改为 unique_ptr

在这种情况下,我通常想做什么?如果有一种方法可以“取消智能”指针,就会告诉我unique_ptr 不是正确的智能指针。

在我转向其他事物之前,C++ 是我选择的语言。回来看到所有的模式和做法都完全改变了,这有点令人震惊。

【问题讨论】:

  • 我认为答案取决于btCollisionDispatcher 是要分享所有权还是取得所有权?如果是后者 - 你能不能改变它来接受unique_ptr?如果是前者,则必须将其更改为 shared_ptr 并传递。
  • disp 将持有cc 并使用它直到它被破坏。它希望您会在其他地方使用它,例如当我稍后调用 btWorld 构造函数时,但据我所知,它不会在自己的范围之外共享指针。
  • 这可能与您的问题无关,但正如您所说,您来自托管语言背景,请确保不要过多地发送垃圾智能指针,并始终首先考虑自动存储。只是一个小而重要的建议,不得不说。
  • "在这种情况下我通常想要做什么?" Read std::unique_ptr's documentation.
  • 使用托管语言可以做的最好的事情就是忘记new

标签: c++ c++11 smart-pointers


【解决方案1】:

有一个get() 成员函数为您提供unique_ptr 持有的原始指针。不过,这不会导致 unique_ptr 放弃所有权,因此仍会进行适当的清理(小心存储该原始指针!)。

还有一个release() 成员函数,它放弃了所有权。这意味着你又回到了哑指针的土地上,清理工作是你的全部责任。

我无法理解为什么代码首先使用new 而不是just using automatic storage objects,但我会假装这是有原因的......

【讨论】:

  • 谢谢,编译成功。 get() 在这种情况下是惯用/正确的选项吗?
  • 如果您传递指针的代码不负责清理(从项目符号站点看起来就是这种情况),是的,get() 是正确的选择。
  • 我认为一般来说,如果我创建和删除对象,我拥有它——所以我可以使用get()?
  • @Rei 是的,这里的所有权意味着“清理的责任”。
  • 谢谢,这非常有用,尤其是release() 正在帮助我处理一些棘手的遗留代码。
【解决方案2】:

get 成员函数返回底层指针,并且可以与现有代码一起使用,只要该代码不管理您传入的内存。

【讨论】:

    猜你喜欢
    • 2021-03-18
    • 2015-05-02
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多