3 回答
TA贡献1873条经验 获得超9个赞
一个很好的例子是缓存。
对于最近访问的对象,您希望将其保留在内存中,因此请牢牢指向它们。您会定期扫描缓存并确定最近未访问过哪些对象。您不需要将它们保留在内存中,因此可以摆脱强指针。
但是,如果该对象正在使用中,并且其他一些代码持有指向该对象的强大指针怎么办?如果缓存摆脱了指向对象的唯一指针,则它将再也找不到它。因此,高速缓存将微弱的指针指向需要查找的对象(如果它们恰好留在内存中)。
这正是弱指针的作用-如果对象仍然存在,它可以让您定位它,但是如果其他对象不需要它,则无法将其保留在对象周围。
TA贡献1860条经验 获得超8个赞
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()
{
// OLD, problem with dangling pointer
// PROBLEM: ref will point to undefined data!
int* ptr = new int(10);
int* ref = ptr;
delete ptr;
// NEW
// SOLUTION: check expired() or lock() to determine if pointer is valid
// empty definition
std::shared_ptr<int> sptr;
// takes ownership of pointer
sptr.reset(new int);
*sptr = 10;
// get pointer to data without taking ownership
std::weak_ptr<int> weak1 = sptr;
// deletes managed object, acquires new pointer
sptr.reset(new int);
*sptr = 5;
// get pointer to new data without taking ownership
std::weak_ptr<int> weak2 = sptr;
// weak1 is expired!
if(auto tmp = weak1.lock())
std::cout << *tmp << '\n';
else
std::cout << "weak1 is expired\n";
// weak2 points to new data (5)
if(auto tmp = weak2.lock())
std::cout << *tmp << '\n';
else
std::cout << "weak2 is expired\n";
}
TA贡献1812条经验 获得超5个赞
另一个答案,希望更简单。(对于其他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 ptr
if( !tempParentSharedPtr ) {
// yes, it may fail if the parent was freed since we stored weak_ptr
} else {
// do stuff
}
// tempParentSharedPtr is released when it goes out of scope
- 3 回答
- 0 关注
- 1090 浏览
添加回答
举报