C++的std::weak_ptr怎么用?和shared_ptr有什么區別?

std::weak_ptr用于解決循環引用問題。當兩個對象互相持有對方的shared_ptr時,會形成循環引用,導致內存無法釋放。通過將其中一個引用改為weak_ptr,可打破循環。使用時需通過lock()轉換為shared_ptr并檢查有效性。它不擁有資源,不影響對象生命周期,適用于緩存、觀察者模式等場景。

C++的std::weak_ptr怎么用?和shared_ptr有什么區別?

std::weak_ptr 是 c++ 中智能指針家族的一員,它和 std::shared_ptr 一起使用,主要用于解決循環引用的問題。它本身并不擁有資源,而是對 shared_ptr 所管理的對象的一個“弱引用”。這意味著它不會增加對象的引用計數,也不會阻止對象被釋放。


為什么需要 weak_ptr?

在使用 shared_ptr 的時候,如果兩個對象互相持有對方的 shared_ptr,就很容易造成循環引用,導致內存無法釋放。

舉個簡單的例子:

立即學習C++免費學習筆記(深入)”;

struct B;  struct A {     std::shared_ptr<B> ptr; };  struct B {     std::shared_ptr<A> ptr; };

如果創建了兩個對象,并讓它們互相引用:

auto a = std::make_shared<A>(); auto b = std::make_shared<B>(); a->ptr = b; b->ptr = a;

這個時候,a 和 b 都有一個引用計數為 2(自身 + 被對方引用),當超出作用域后,它們的引用計數只會減到 1,不會真正釋放內存。

這時候就需要 weak_ptr 來打破這種循環依賴。


weak_ptr 的基本用法

weak_ptr 不能直接訪問對象,必須通過 lock() 方法轉換成 shared_ptr 來臨時獲得資源所有權。

修改上面的例子:

struct A;  struct B {     std::weak_ptr<A> ptr;  // 改為 weak_ptr };  struct A {     std::shared_ptr<B> ptr; };

這樣,當 a 持有 b 的 shared_ptr,而 b 只是弱引用 a,就不會形成循環引用。當 a 離開作用域時,引用計數正常歸零,對象會被釋放。

訪問 weak_ptr 內容時要這樣做:

std::shared_ptr<A> temp = b.ptr.lock(); if (temp) {     // 對象還活著,可以安全使用 temp } else {     // 對象已經被釋放了 }

shared_ptr 和 weak_ptr 的區別

特性 shared_ptr weak_ptr
是否擁有資源 ? 是 ? 否
會增加引用計數嗎 ? 會 ? 不會
能否直接訪問對象 ? 可以 ? 必須轉成 shared_ptr
是否影響對象生命周期 ? 影響 ? 不影響
主要用途 共享資源所有權 監控資源、打破循環引用

簡單來說:

  • 如果你希望多個地方共享一個對象的生命期,用 shared_ptr。
  • 如果只是想觀察或者偶爾訪問這個對象,不想影響它的生命周期,就用 weak_ptr。

使用 weak_ptr 的幾個注意事項

  • 每次使用前都要調用 lock() 并檢查是否為空,因為對象可能已經被釋放了。
  • 不要長期持有 lock() 返回的 shared_ptr,否則可能會延長對象的生命周期,甚至重新引入循環引用的風險。
  • weak_ptr 適合用于緩存、觀察者模式、樹結構中的父節點引用等場景
  • 它本身不支持 operator-> 或 operator*,只能通過轉換為 shared_ptr 后訪問。

基本上就這些。掌握好 weak_ptr 的使用,能有效避免一些常見的資源管理問題,特別是在復雜對象圖中。

以上就是C++的std::weak_ptr怎么用?和sha

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享