4:std::weak_ptr
std::weak_ptr从shared_ptr产生,特性:
std::weak_ptr
是一种智能指针,它对被 std::shared_ptr 管理的对象存在非拥有性(“弱”)引用。在访问所引用的对象前必须先转换为 std::shared_ptr。std::weak_ptr
用来表达临时所有权的概念:当某个对象只有存在时才需要被访问,而且随时可能被他人删除时,可以使用std::weak_ptr
来跟踪该对象。需要获得临时所有权时,则将其转换为 std::shared_ptr,此时如果原来的 std::shared_ptr 被销毁,则该对象的生命期将被延长至这个临时的 std::shared_ptr 同样被销毁为止。- std::weak_ptr不会增加引用计数
std::weak_ptr lock() 方法可以取得其相应的shared_ptr,若shared_ptr在此时已被析构则返回空指针,调用lock()即创建一个shared_ptr引用,因此会使引用计数+1
示例代码:
1 #include <iostream> 2 #include <memory> 3 4 std::weak_ptr<int> gw; 5 6 void f() 7 { 8 if (auto spt = gw.lock()) { // 使用之前必须复制到 shared_ptr 9 std::cout << *spt << "\n"; 10 } 11 else { 12 std::cout << "gw is expired\n"; 13 } 14 } 15 16 int main() 17 { 18 { 19 auto sp = std::make_shared<int>(42); 20 gw = sp; 21 22 f(); 23 } 24 25 f(); 26 }
《Effective Modern C++》中的典型应用:
1 std::shared_ptr<const Widget> fastLoadWidget(WIDGET_ID id){ 2 static std::unordered_map<WIDGET_ID, std::weak_ptr<Widget> > cache; 3 auto objPtr = cache[id].lock(); 4 if (!objPtr) { 5 objPtr = loadWidget(id); 6 cache[id] = objPtr; 7 } 8 return objPtr; 9 }