![](/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.