随着 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 回答
就个人而言,这就是我(或多或少)这样做的方式:
unique_ptrs 仅供所有权使用
raw pointers 意味着谁给了我原始指针,保证该对象的生命周期匹配或超过我的生命 .
shared_ptrs 用于共享所有权
weak_ptrs 适用于系统在使用之前检查对象是否仍然存在的情况 . 这在我的代码中很少见,因为我发现系统保证它通过子系统的任何东西的生命周期都很清晰(在这种情况下我使用原始指针)
到目前为止,我使用了比shared_ptrs更多的unique_ptrs,以及比弱指针更多的原始指针 .
当需要多个东西拥有一个资源时使用
shared_ptr
(那些拥有的东西可能会进入和退出"random"范围内),当一个东西拥有资源时使用unique_ptr
,当你需要引用时使用原始指针它并不拥有它(并期望此引用的持续时间不会超过资源的存在时间) .还有第四种类型,一种叫做
weak_ptr
的原始指针,用于shared_ptr
. 您可以使用它来引用shared_ptr
而不实际拥有它;然后,您可以检查对象是否仍然存在并使用它 .标准库中唯一的非拥有智能指针是
std::weak_ptr
. 但是,要使用它,实际拥有对象需要将指针对象保存在std::shared_ptr
中 .我假设您之前使用了
std::unique_ptr
. 如果你现在将它们转换为shared_ptr
,那么你的好处就是你的非拥有指针可以知道丢失的拥有指针是引用,而原始指针可以悬空而没有任何机会让非拥有组件检测到这一点 . 但是,shared_ptr
将导致(非常?)小的性能和内存开销超过unique_ptr
.就个人而言,我建议在一般情况下使用一个
shared_ptr
和许多weak_ptr
而不是一个unique_ptr
和许多原始指针,如果确实存在性能问题,请使用unique_ptr
!