首页 文章

C 11:用std :: shared_ptr()替换所有非拥有的原始指针?

提问于
浏览
52

随着 std::unique_ptr 的出现,瑕疵 std::auto_ptr 终于可以得到休息 . 所以在过去的几天里,我一直在改变我的代码以使用智能指针并从我的代码中消除所有 delete .

虽然valgrind说我的代码是内存清晰的,但智能指针的语义丰富性将使代码更清晰,更易于理解 .

在大多数代码中,翻译很简单:使用 std::unique_ptr 代替拥有对象持有的原始指针,抛出 delete ,并根据需要小心地调用 get()reset()move() 调用,以便与其余的代码 .

我现在正在将 non-owning raw pointers 转换为智能指针 .

由于我小心对象的生命周期(我确保我的模块只依赖于一个方向),valgrind告诉我,我没有任何未初始化的读取,悬空指针或泄漏 . 所以,从技术上讲,我现在可以单独留下那些 non-owning raw pointers .

但是,一个选项是将那些 non-owning raw pointers 更改为 std::shared_ptr ,因为我知道它们是非循环的 . 或者,将它们留作原始指针会更好吗?

我需要智能指针的资深用户提供一些建议,告诉你使用什么经验法则来决定是按原样保留 non-owning raw pointers 还是将它们翻译成 std::shared_ptr ,记住我经常对我的代码进行单元测试和修改 .

编辑:我可能误解 std::shared_ptr 的使用 - 它们可以与 std::unique_ptr 一起使用,还是如果我使用 std::shared_ptr ,所有句柄也应该是 std::shared_ptr

3 回答

  • 8

    就个人而言,这就是我(或多或少)这样做的方式:

    • unique_ptrs 仅供所有权使用

    • raw pointers 意味着谁给了我原始指针,保证该对象的生命周期匹配或超过我的生命 .

    • shared_ptrs 用于共享所有权

    • weak_ptrs 适用于系统在使用之前检查对象是否仍然存在的情况 . 这在我的代码中很少见,因为我发现系统保证它通过子系统的任何东西的生命周期都很清晰(在这种情况下我使用原始指针)

    到目前为止,我使用了比shared_ptrs更多的unique_ptrs,以及比弱指针更多的原始指针 .

  • 96

    当需要多个东西拥有一个资源时使用 shared_ptr (那些拥有的东西可能会进入和退出"random"范围内),当一个东西拥有资源时使用 unique_ptr ,当你需要引用时使用原始指针它并不拥有它(并期望此引用的持续时间不会超过资源的存在时间) .

    还有第四种类型,一种叫做 weak_ptr 的原始指针,用于 shared_ptr . 您可以使用它来引用 shared_ptr 而不实际拥有它;然后,您可以检查对象是否仍然存在并使用它 .

  • 11

    标准库中唯一的非拥有智能指针是 std::weak_ptr . 但是,要使用它,实际拥有对象需要将指针对象保存在 std::shared_ptr 中 .

    我假设您之前使用了 std::unique_ptr . 如果你现在将它们转换为 shared_ptr ,那么你的好处就是你的非拥有指针可以知道丢失的拥有指针是引用,而原始指针可以悬空而没有任何机会让非拥有组件检测到这一点 . 但是, shared_ptr 将导致(非常?)小的性能和内存开销超过 unique_ptr .

    就个人而言,我建议在一般情况下使用一个 shared_ptr 和许多 weak_ptr 而不是一个 unique_ptr 和许多原始指针,如果确实存在性能问题,请使用 unique_ptr

相关问题