传递给方法时,我应该将shared_ptr转换为weak_ptr吗?

Phi*_*ipp 8 c++ shared-ptr

关于这个主题已经有几个问题,但我仍然不确定该怎么做:我们的代码库shared_ptr在许多地方使用.我必须承认,在编写时我们没有明确定义所有权.

我们有一些方法

 void doSomething(shared_ptr<MyClass> ptr)
 {
      //doSomething() is a member function of a class, but usually won't store the ptr
      ptr->foo();
      ...
 }
Run Code Online (Sandbox Code Playgroud)

在发现了第一个(间接的)循环依赖之后,我想纠正我们设计中的错误.但我不确定如何.从上面改变方法有什么好处

 void doSomething(weak_ptr<MyClass> ptr)
 {
      shared_ptr<MyClass> ptrShared = ptr.lock();
      ptrShared->foo();
      ...
 }
Run Code Online (Sandbox Code Playgroud)

我也很困惑,因为有些人说(包括谷歌风格指南),首先要确保所有权的正确性(这可能意味着引入许多weak_ptrs,例如在上述方法的例子中,但对许多成员变量也是如此)我们有).其他人说(请参阅下面的链接)你应该使用weak_ptr来打破循环依赖.但是,检测它们并不总是很容易,所以我想我是否真的应该使用shared_ptr,直到我遇到问题(并实现它们),然后修复它们?

谢谢你的想法!

也可以看看

Jam*_*lis 6

我们没有明确定义所有权.

你需要清楚地定义谁拥有什么.没有其他办法可以解决这个问题.随意换出的一些用途shared_ptrweak_ptr不会让事情变得更好.


Nat*_*ael 5

将上面的设计从shared_ptr更改为weak_ptr没有任何好处。获得所有权并不是要使用weak_ptr,而是要管理谁在很长一段时间内存储shared_ptr。如果我将一个shared_ptr传递给一个方法,假设我没有将该shared_ptr作为该方法的一部分存储到我的对象的字段中,那么我没有更改谁拥有该数据。

根据我的经验,使用weak_ptr的唯一原因是当你绝对必须有一个指针循环并且你需要打破这个循环时。但首先您应该考虑是否可以修改设计以消除循环。

我通常不鼓励混合共享指针和原始指针。不可避免地会发生(尽管可能不应该)需要将原始指针传递给采用该类型的shared_ptr 的函数。一个weak_ptr可以安全地转换为一个shared_ptr,使用原始指针你就不走运了。更糟糕的是,对shared_ptr缺乏经验的开发人员可能会从该原始指针创建一个新的shared_ptr并将其传递给函数,导致该指针在函数返回时被删除。(我实际上必须修复生产代码中的这个错误,所以是的,它确实发生了:))