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

kfm*_*e04 57 c++ memory smart-pointers c++11

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

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

在大多数代码中,转换很简单:std::unique_ptr用于代替拥有对象持有的原始指针,抛弃delete,仔细撒取get(),reset()move()根据需要调用,以便与其余代码良好地连接.

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

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

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

我需要智能指针的资深用户提供一些建议,告诉你使用什么经验法则来决定是否保留非拥有的原始指针,或将它们翻译成std::shared_ptr,请记住我经常进行单元测试和valgrind我的码.

编辑:我可能误解了它的使用std::shared_ptr- 它们是否可以结合使用std::unique_ptr,或者如果我使用的话std::shared_ptr,所有句柄也应该是这样的情况std::shared_ptr

Dav*_*vid 104

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

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

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

  • +1不要轻易做事.不要让简单的事情复杂化. (13认同)
  • @LCIDFire不,我几乎从不传递一个原始指针,该指针可选地为null; 这不是通过原始指针传递的原因.当对象仅用于方法的范围时,我通过引用传递.当方法存储指针(通常作为类成员)超出其调用范围时,我通过指针传递.显然,你可以把传递给你的参考地址,但我相信做我上面说的更清楚. (9认同)
  • +1您的观察结果与我在该领域的有限经验一致 - 很高兴获得肯定和明确的使用陈述 (3认同)

GMa*_*ckG 11

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

还有第四种类型,一种shared_ptr叫做raw-pointer-for- s的东西weak_ptr.你用它来指代一个shared_ptr没有实际拥有它; 然后,您可以检查对象是否仍然存在并使用它.


ltj*_*jax 8

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

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

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

  • +1 使用 `weak_ptr` 来保存指针引用,即使只有一个所有者。`weak_ptr` 的好处在于它实际上*检查*以查看对象是否消失。它使您能够进行一些验证以查看对象是否已被删除。裸指针无法做到这一点。 (3认同)