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

时间:2011-12-01 08:47:30

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

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

尽管valgrind说我的代码是内存清晰的,但智能指针的语义丰富性将使代码更清晰,更容易理解。

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

我现在正在将非拥有原始指针转换为智能指针。

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

但是,一种选择是将那些非拥有原始指针更改为std::shared_ptr,因为我知道它们是非循环的。或者,将它们留作原始指针会更好吗?

我需要智能指针的资深用户提供一些建议,告诉您使用哪些经验法则来决定是否保留非拥有原始指针,或将其转换为std::shared_ptr请记住,我经常对我的代码进行单元测试和修改。

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

3 个答案:

答案 0 :(得分:104)

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

  • unique_ptrs 仅供所有权使用
  • 原始指针意味着谁给了我原始指针,保证该对象的生命周期匹配或超过我的生命。
  • shared_ptrs 用于共享所有权
  • weak_ptrs 适用于系统在使用之前检查对象是否仍然存在的情况。这在我的代码中很少见,因为我发现系统保证它通过子系统的任何生命周期都很清晰(在这种情况下我使用原始指针)

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

答案 1 :(得分:11)

当您需要多个拥有资源的东西时使用shared_ptr(拥有的东西可以“随机”进入和退出范围),当一个东西拥有资源时使用unique_ptr ,当你只需要引用它而不拥有它时使用原始指针(并期望这个引用的持续时间不会长于资源)。

还有第四种类型,一种原始指针 - shared_ptr,称为weak_ptr。您可以使用它来引用shared_ptr而不实际拥有它;然后,您可以检查对象是否仍在那里并使用它。

答案 2 :(得分:8)

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

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

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