![](/img/trans.png)
[英]Did I understand correctly the point of Scott Meyers' example of std::weak_ptr?
[英]Understanding of Scott Meyers' third example of std::weak_ptr
Effective Modern C++第 137 页的最后一个例子描绘了一个数据结构的场景,其中包含对象A
、 B
和C
,通过std::shared_ptr
以下列方式相互连接:
std::shared_ptr std::shared_ptr
A ─────────────────▶ B ◀───────────────── C
对我来说,这意味着该对象的类A
和C
是实例(两个不相关的类,在一般情况)必须包含std::shared_ptr<classOfB>
构件。
然后假设我们需要一个从B
返回到A
的指针,并列出了可用的选项:指针可以是原始的、共享的或弱的,最后一个被选为最佳候选者。
std::shared_ptr std::shared_ptr
A ─────────────────▶ B ◀───────────────── C
▲ │
│ std::weak_ptr │
└────────────────────┘
我确实理解前两个选项的弱点(啊哈),但我也看到第三个选项要求成员A
已经由某个std::shared_ptr
管理,否则std::weak_ptr
怎么能指向它呢?
然而,这本书并没有提到这个“限制”/假设/任何东西,所以事实是
std::weak_ptr
需要一个已经存在的std::shared_ptr
到同一个对象的确切原因,假设是显而易见的,但我认为这有点奇怪,它甚至在示例的开头都没有提到。我问这个问题是为了理解这一点。
你是对的,你的第三个要点是正确的。 std::weak_ptr
始终引用现有的std::shared_ptr
。 因此,一旦我们决定 A 将包含一个shared_ptr<BClass>
并且 A 的实例作为shared_ptr<AClass>
进行管理,我们就可以在后面使用weak_ptr<AClass>
- 从 B 到 A 的参考。
在典型的用例中,您可以拥有一个管理三个成员的 D 类shared_ptr<AClass> a;
, shared_ptr<BClass> b;
和shared_ptr<CClass> c;
, 然后 D 类中的某个成员函数做了a->SetB(b);
, c->SetB(b);
, b->SetA(a);
, SetB 成员函数使用 shared_ptr's 和 SetA 使用weak_ptr(或在成员函数中转换为weak_ptr)。 正如您所说,如果 D 确实以任何其他方式存储了对 A 的引用,例如原始指针AClass* a;
或一个实例AClass a;
,那么使用weak_ptr 是不可能的。
std::shared_ptr
设计的不幸后果是在共享指针管理的依赖图中不会出现循环。 这意味着一旦 A 通过共享指针指向 B,B 就不能以相同的方式指向 A,因为这将导致内存泄漏(两个对象都将保持活动状态)。
std::weak_ptr
的主要目的是作为弱引用,但在大多数情况下,它仅用作解决此问题的方法。 但是,如果您首先不通过共享指针管理 A 的生命周期,则 B 无论如何都无法跟踪它,因此使用原始指针、引用(或其他一些外来指针)是唯一的选择。 相反,如果您通过共享指针拥有 A,则weak_ptr
是唯一的选择。
在这两种情况下,选择完全取决于您之前管理 A 的决定,这是您在这里必须做的事情(可能通过一个同时引用 A 和 C 的对象)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.