猿问

什么时候std :: weak_ptr有用?

我开始研究C ++ 11的智能指针,但看不到任何有用的用法std::weak_ptr。有人可以告诉我什么时候std::weak_ptr有用/必要吗?



繁星点点滴滴
浏览 1092回答 3
3回答

眼眸繁星

一个很好的例子是缓存。对于最近访问的对象,您希望将其保留在内存中,因此请牢牢指向它们。您会定期扫描缓存并确定最近未访问过哪些对象。您不需要将它们保留在内存中,因此可以摆脱强指针。但是,如果该对象正在使用中,并且其他一些代码持有指向该对象的强大指针怎么办?如果缓存摆脱了指向对象的唯一指针,则它将再也找不到它。因此,高速缓存将微弱的指针指向需要查找的对象(如果它们恰好留在内存中)。这正是弱指针的作用-如果对象仍然存在,它可以让您定位它,但是如果其他对象不需要它,则无法将其保留在对象周围。

桃花长相依

std::weak_ptr是解决悬空指针问题的一种很好的方法。仅使用原始指针就不可能知道所引用的数据是否已被释放。相反,通过std::shared_ptr管理数据并提供std::weak_ptr给数据用户,用户可以通过调用expired()或来检查数据的有效性lock()。您无法std::shared_ptr单独做到这一点,因为所有std::shared_ptr实例都共享在删除所有实例之前都不会删除的数据的所有权std::shared_ptr。这是如何使用来检查悬空指针的示例lock():#include <iostream>#include <memory>int main(){&nbsp; &nbsp; // OLD, problem with dangling pointer&nbsp; &nbsp; // PROBLEM: ref will point to undefined data!&nbsp; &nbsp; int* ptr = new int(10);&nbsp; &nbsp; int* ref = ptr;&nbsp; &nbsp; delete ptr;&nbsp; &nbsp; // NEW&nbsp; &nbsp; // SOLUTION: check expired() or lock() to determine if pointer is valid&nbsp; &nbsp; // empty definition&nbsp; &nbsp; std::shared_ptr<int> sptr;&nbsp; &nbsp; // takes ownership of pointer&nbsp; &nbsp; sptr.reset(new int);&nbsp; &nbsp; *sptr = 10;&nbsp; &nbsp; // get pointer to data without taking ownership&nbsp; &nbsp; std::weak_ptr<int> weak1 = sptr;&nbsp; &nbsp; // deletes managed object, acquires new pointer&nbsp; &nbsp; sptr.reset(new int);&nbsp; &nbsp; *sptr = 5;&nbsp; &nbsp; // get pointer to new data without taking ownership&nbsp; &nbsp; std::weak_ptr<int> weak2 = sptr;&nbsp; &nbsp; // weak1 is expired!&nbsp; &nbsp; if(auto tmp = weak1.lock())&nbsp; &nbsp; &nbsp; &nbsp; std::cout << *tmp << '\n';&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; std::cout << "weak1 is expired\n";&nbsp; &nbsp; // weak2 points to new data (5)&nbsp; &nbsp; if(auto tmp = weak2.lock())&nbsp; &nbsp; &nbsp; &nbsp; std::cout << *tmp << '\n';&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; std::cout << "weak2 is expired\n";}

ABOUTYOU

另一个答案,希望更简单。(对于其他Google员工)假设您有Team和Member对象。显然,这是一种关系:Team对象将具有指向的指针Members。而且成员也可能有指向其Team对象的后向指针。然后,您将有一个依赖周期。如果使用shared_ptr,则放弃引用时将不再自动释放对象,因为它们以循环方式相互引用。这是内存泄漏。您可以使用来打破这一点weak_ptr。“所有者”通常使用shared_ptr与“拥有”使用weak_ptr它的父,并将其转换暂时到shared_ptr时,它需要访问它的父。存储一个弱ptr:weak_ptr<Parent> parentWeakPtr_ = parentSharedPtr; // automatic conversion to weak from shared然后在需要时使用它shared_ptr<Parent> tempParentSharedPtr = parentWeakPtr_.lock(); // on the stack, from the weak ptrif( !tempParentSharedPtr ) {&nbsp; // yes, it may fail if the parent was freed since we stored weak_ptr} else {&nbsp; // do stuff}// tempParentSharedPtr is released when it goes out of scope
随时随地看视频慕课网APP
我要回答