为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候std :: weak_ptr有用?

什么时候std :: weak_ptr有用?

C++
繁星点点滴滴 2020-02-03 14:25:23
我开始研究C ++ 11的智能指针,但看不到任何有用的用法std::weak_ptr。有人可以告诉我什么时候std::weak_ptr有用/必要吗?
查看完整描述

3 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

一个很好的例子是缓存。

对于最近访问的对象,您希望将其保留在内存中,因此请牢牢指向它们。您会定期扫描缓存并确定最近未访问过哪些对象。您不需要将它们保留在内存中,因此可以摆脱强指针。

但是,如果该对象正在使用中,并且其他一些代码持有指向该对象的强大指针怎么办?如果缓存摆脱了指向对象的唯一指针,则它将再也找不到它。因此,高速缓存将微弱的指针指向需要查找的对象(如果它们恰好留在内存中)。

这正是弱指针的作用-如果对象仍然存在,它可以让您定位它,但是如果其他对象不需要它,则无法将其保留在对象周围。


查看完整回答
反对 回复 2020-02-03
?
桃花长相依

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";

}


查看完整回答
反对 回复 2020-02-03
?
ABOUTYOU

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


查看完整回答
反对 回复 2020-02-03
  • 3 回答
  • 0 关注
  • 1085 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信