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

2021-12-21 00:00:00 memory c++ c++11 smart-pointers

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

With the advent of std::unique_ptr, the blemished std::auto_ptr can finally be put to rest. So for the last several days, I have been changing my code to use smart pointers and to eliminate all delete from my code.

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

Although valgrind says my code is memory-clean, the semantic richness of smart pointers will make for cleaner and easier-to-understand code.

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

In most of the code, the translation is simple: use std::unique_ptr for in place of the raw pointers held by the owning objects, throw out delete, and carefully sprinkle get(), reset() and move() calls, as needed, to interface well with the rest of the code.

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

I am at the point where I am translating non-owning raw pointers to smart pointers now.

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

Since I was careful with the lifetimes of my objects (I ensure my modules only depend in one direction), valgrind tells me that I don't have any uninitialized reads, dangling pointers, or leaks. So, technically, I could just leave those non-owning raw pointers alone now.

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

However, one option is to change those non-owning raw pointers to std::shared_ptr because I know they are acyclic. Or, would it be better to leave them as raw pointers?

我需要智能指针资深用户的一些建议,关于您使用哪些经验法则来决定是保持非拥有原始指针原样,还是将它们转换为std::shared_ptr, 请记住,我经常对代码进行单元测试和 valgrind.

I need some advice from veteran users of smart pointers as to what rules of thumb you use to decide whether to keep non-owning raw pointers as-is, or to translate them into std::shared_ptr, keeping in mind that I constantly unit-test and valgrind my code.

我可能误解了 std::shared_ptr 的使用 - 它们可以与 std::unique_ptr 结合使用,还是如果我用的是std::shared_ptr,所有的句柄也应该是std::shared_ptr?

I might be misunderstanding the use of std::shared_ptr - can they be used in conjunction with std::unique_ptr, or is it the case that if I use std::shared_ptr, all handles should also be std::shared_ptr?

推荐答案

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

Personally, this is how I (more or less) do it:

  • unique_ptrs 为独资
  • 原始指针是指给我原始指针的人保证该对象的生命周期匹配或超过我的生命周期.
  • shared_ptrs 用于共享所有权
  • weak_ptrs 用于当系统想要在使用对象之前检查对象是否仍然存在时.这在我的代码中很少见,因为我发现让系统保证它通过它的子系统的任何东西的生命周期会更清晰(在这种情况下我使用原始指针)
  • unique_ptrs are for sole ownership
  • raw pointers mean whoever gave me the raw pointer guarantees the lifetime of that object to match or exceed my lifetime.
  • shared_ptrs are for shared ownership
  • weak_ptrs are for when a system wants to check if the object still exists before using it. This is rare in my code since I find it cleaner to have a system guarantee the lifetime of anything it passes it's subsystems (in which case I use a raw pointer)

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

By far I use more unique_ptrs than shared_ptrs, and more raw pointers than weak pointers.

相关文章