簡體   English   中英

了解 Scott Meyers 的第三個 std::weak_ptr 示例

[英]Understanding of Scott Meyers' third example of std::weak_ptr

Effective Modern C++第 137 頁的最后一個例子描繪了一個數據結構的場景,其中包含對象ABC ,通過std::shared_ptr以下列方式相互連接:

   std::shared_ptr       std::shared_ptr
A ─────────────────▶ B ◀───────────────── C

對我來說,這意味着該對象的AC是實例(兩個不相關的類,在一般情況)必須包含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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM