std::weak_ptr 是 C++11 引入的弱引用智能指針,不佔有對象所有權,不增加引用計數。主要用於打破 shared_ptr 循環引用及緩存/觀察者模式中臨時訪問對象。
lock() 生成 shared_ptr 才能訪問對象;若對象已銷毀,lock() 返回空指針。expired() 判斷對象是否仍存活。shared_ptr 隱式構造,也可 reset() 置空。問題:Man 持有 shared_ptr,Woman 持有 shared_ptr,引用計數永遠 ≥ 2,析構函數永不調用 → 內存洩漏。
解決:一方改用 weak_ptr:
#include <memory>
#include <iostream>
struct Woman; // 前向宣告
struct Man {
std::shared_ptr wife; // 強引用
~Man() { std::cout << "Man dtor\n"; }
};
struct Woman {
std::weak_ptr husband; // 弱引用,不增加計數
~Woman() { std::cout << "Woman dtor\n"; }
};
int main() {
auto man = std::make_shared();
auto woman = std::make_shared();
man->wife = woman;
woman->husband = man; // 不構成循環
// 離開作用域時 man、woman 計數歸 0,正常析構
}
線程 A 為主邏輯,B/C 為可選輔助任務。B/C 持有 weak_ptr 觀察 A 的資源:
std::weak_ptrgw; void worker() { if (auto sp = gw.lock()) { // 臨時升級為強引用 sp->doSomething(); } else { std::cout << "Resource already released\n"; } } void testScope() { auto sp = std::make_shared (); gw = sp; worker(); // 正常訪問 sp.reset(); // 主邏輯釋放 worker(); // 提示已釋放 }
TestWeakPtrScope_1 42 // lock 成功,對象存活 42 // sp1 持有 strong ref,對象仍存活 TestWeakPtrScope_2 42 // lock 成功 gw is expired // 離開作用域後 sp 銷毀,gw.expired() 為真
weak_ptr,定期掃描 expired() 清理失效項。lock() 返回的 shared_ptr 保證線程安全(引用計數原子操作)。weak_ptr 替代裸指針;只有在「可能需要訪問、但不應延長生命週期」時才使用。