← 模式

弱引用

12345678910111213141516171819202122232425262728293031323334#include <memory> class bar; class foo { public: foo(const std::shared_ptr<bar>& b) : forward_reference{b} { } private: std::shared_ptr<bar> forward_reference; }; class bar { public: void set_back_reference(const std::weak_ptr<foo>& f) { this->back_reference = f; } void do_something() { std::shared_ptr<foo> shared_back_reference = this->back_reference.lock(); if (shared_back_reference) { // 使用 *shared_back_reference } } private: std::weak_ptr<foo> back_reference; };

此模式采用 CC0 公共领域贡献 许可。

需要 c++11 或更新版本。

意图

维持一个对共享动态分配对象的非持有引用,以打破循环依赖。

描述

std::weak_ptr 类型表示一个对共享所有权(std::shared_ptr)的动态分配对象的非持有引用。由于弱引用不会增加其所指向的被管理对象的引用计数,因此当所有 std::shared_ptr 放弃所有权时,该对象随时可能被销毁。然而,std::weak_ptr 可以转换为 std::shared_ptr,以提供临时所有权并安全地访问对象。

在示例代码中,我们有两个类:第 5–14 行foo第 16–30 行bar。一个 foo 对象拥有一个 bar 对象的部分所有权(第 13 行),而 bar 需要某种形式的反向引用,指回拥有它的 foo。如果这个反向引用是 std::shared_ptr<foo>,就会引入循环依赖,导致两个对象都无法被销毁。如果它是一个普通的引用类型(foo&),则在使用它时可能引用一个已被删除的对象,因为 foo 的生命周期与 bar 是独立的。

解决方案是使用 std::weak_ptr<foo>,如第 33 行所示。当 bar 需要使用 foo 时,它通过在 std::weak_ptr 上调用 lock 来获取临时的共享所有权(第 26 行),以此检查 foo 是否仍然存在。如果返回的 std::shared_ptr 不为空,bar 就可以安全地使用它来访问 foo 对象(第 27–29 行)。

贡献者

  • Joseph Mansfield
  • dyp-cpp
  • Migrant Coder

最后更新

2017年12月10日

来源

在 GitHub 上 Fork 此模式

分享