智能指针 weak_ptr

weak_ptr (到std:shared_ptr 所管理对象的弱引用)

正式介绍weak_ ptr 之前,先来回忆一下 shared_ptr 的一些知识。

  • 我们知道shared_ptr 是采用引用计数的智能指针,多个shared_ptr
    实例可以指向同一个动态对象,并维护了一个共享的引用计数器。
  • 对于引用计数法实现的计数,总是避免不了循环引用(或环形引用)的问题,shared_ptr 也不例外。为了解决类似这样的问题,C++11 引入了weak ptr,来打破这种循环引用。

循环引用Demo

class Child;
class Parent
{
public:
    shared_ ptr<Child> child;
    ~Parent() { cout << "Bye Parent" << endl; }
    void hi() const { cout << "Hello" << endl; }
};
class Child
{
    public:
    shared_ ptr<Parent> parent ;
    ~Child() { cout << "Bye Child" << endl; }
};

int main()
{
    shared_ ptr<Parent> parent = make_ shared<Parent>( );
    shared_ ptr<Child> child = make_ shared<Child>() ;
    parent->child = child;
    child->parent = parent;
    child->parent->hi();
    return 0; .
}

输出为
Hello

weak_ ptr 是什么?

  • weak_ptr是为了配合shared_ptr 而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ ptr 不会改变shared_ptr的引用计数。
  • 不论是否有weak _ptr指向,一旦最后一个指向对象的 shared_ptr被销毁,对象就会被释放。
  • 从这个角度看,weak_ptr更像是shared_ptr 的一个助手而不是智能指针。

weak_ptr 如何使用?

1.如何创建weak_ ptr 实例

  • 当我们创建一个 weak_ptr时,需要用一个shared_ptr实例来初始化weak _ptr, 由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值。
int main()
{
    shared_ ptr<int> sp(new int(5));
    cout << "创建前sp的引用计数:<< sp.use_ count() << end1l; 
    // use_count = 1
    weak_ ptr<int> Wp(sp);
    cout << "创建后sp的引用计数:<< sp.use_ count() << endl;
    // use_ count = 1
    return 0;
}

2.如何判断weak_ptr 指向对象是否存在

  • 既然weak_ptr 并不改变其所共享的shared_ ptr 实例的引用计数,那就可能存在weak_ptr指向的对象被释放掉这种情况。
  • 这时,我们就不能使用weak _ptr 直接访问对象。那么我们如何判断weak_ptr 指向对象是否存在呢?

C+ +中提供了lock 函数来实现该功能。

  • 如果对象存在,lock)函数返回一个指向共享对象的shared_ptr,
  • 否则返回一个空shared_ptr.

如何使用weak_ptr

  • weak_ ptr 并没有重载operator->和 operator *操作符,因此不可直接通过weak_ ptr
    使用对象,典型的用法是调用其lock函数来获得shared_ptr 示例,进而访问原始对象。

最后,我们来看看如何使用weak_ptr 来改造最前面的代码,打破循环引用问题。

class Child;
class Parent
{
public:
    weak_ ptr<Child> child; 
    ~Parent() { cout << "Bye Parent" << endl; }
    void hi() const { cout << "Hello" << endl; }
};
class Child
{
public:
    weak_ ptr<Parent> parent; //
    ~Child() { cout << "Bye Child" << endl; }
};

int main()
{
    shared_ ptr<Parent> parent = make_ shared<Parent>();
    shared_ ptr<Child> child = make_ shared<Child>();
    parent->child = child;
    child->parent = parent;
    //child->parent->hi(); //??
    if(child-> expired()) 
    {
         child- >parent.1ock()->hi(); 
    }
    return 0;
输出为
Hello
Bye	Child
Bye Parent

图论

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值