• C++11智能指针weak_ptr


    weak_ptr介绍

    弱引用指针weak_ptr是用来监视shared_ptr的生命周期,是shared_ptr的一个助手。weak_ptr没有重载操作符*和->,因为它不与shared_ptr共享指针,不能操作资源

    weak_ptr主要是通过lock方法转换成shared_ptr获得资源的监测权,它的构造不会增加引用计数Uses_,它的析构也不会减少引用计数Uses_,纯粹只是作为一个旁观者来监视shared_ptr中管理的资源是否存在。weak_ptr还可以用来返回this指针和解决循环引用的问题

    weak_ptr 构造

    只能用shared_ptr对象或者weak_ptr对象初始化weak_ptr,不能用裸指针初始化weak_ptr。由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值Uses_。可以通过use_count()方法来获得当前被管理资源的引用计数Uses_,即管理资源的shared_ptr的数量

    • Uses_:管理资源的shared_ptr的数量,Uses_为0时释放被管理的资源
    • Weaks_:shared_ptr被构造时为1,多一个weak_ptr指向则加1,少一个weak_ptr指向则减1;多一个或少一个shared_ptr指向都不变,只有当Uses_减为0时,才会将Weaks_减1

    【示例一】

    	shared_ptr<Int> sp1(new Int(10));    // Uses_ = 1,Weaks_ = 1
    	weak_ptr<Int> wp(sp1);               // Uses_ = 1,Weaks_ = 2
    	cout << wp.use_count() << endl;      // 1
    	{
    		shared_ptr<Int> sp2(sp1);        // 拷贝构造
    		cout << wp.use_count() << endl;  // Uses_ = 2,Weaks_ = 2
    	} // sp2析构时,会将Uses_从2减为1,此时Weaks_不变,Uses_ = 1,Weaks_ = 2
    	cout << wp.use_count() << endl;      // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    shared_ptr析构时会将引用计数对象的Uses_减1,而不会改变Weaks_,只有当Uses_减为0时,才会将Weaks_减1。Uses_为0时释放被管理的资源,Uses_和Weaks_同时为0时释放引用计数对象。weak_ptr析构时会将Weaks_减1

    在这里插入图片描述

    【示例二】

    	weak_ptr<Int> wp;
    	cout << wp.use_count() << endl;      // 还没有创建引用计数对象,该函数会直接返回0
    	{
    		shared_ptr<Int> sp(new Int(10)); // Uses_ = 1,Weaks_ = 1
    		wp = sp;      // weak_ptr& operator=(const shared_ptr<_Ty2>& _Right)   Uses_ = 1,Weaks_ = 2
    		cout << wp.use_count() << endl;  // 1
    	} // sp析构时,会将Uses_从1减为0,此时Weaks_也从2减为1,Uses_ = 0,Weaks_ = 1
    	cout << wp.use_count() << endl;      // 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    lock方法

    weak_ptr没有重载operator*和operator->操作符,不能直接操作资源,需要调用lock方法或者shared_ptr实例才能访问资源

    expired方法,当引用计数对象Uses_不为0时返回true,否则返回false

    weak_ptr<int> gw;
    
    void func() {
    	if (!gw.expired()) {
    		cout << "not expired" << endl;
    		shared_ptr<int> sp2 = gw.lock();  // Uses_ = 2,Weaks_ = 2
    		cout << sp2.use_count() << endl;  // 2
    	}                                     // sp2析构后,Uses_ = 1,Weaks_ = 2
    	else {
    		cout << "expired" << endl;
    	}
    }
    
    int main() {
    	{
    		shared_ptr<int> sp1(new int(1)); // Uses_ = 1,Weaks_ = 1
    		gw = sp1;                        // Uses_ = 1,Weaks_ = 2
    		func();                          // func退出后,sp2 构,Uses_ = 1,Weaks_ = 1
    	} // 局部作用域退出后,sp1析构,Uses_ = 0,Weaks_ = 1,资源释放,引用计数对象没释放
    
    	func();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    int main() {
    	weak_ptr<Int> wp;
    	{
    		shared_ptr<Int> sp1(new Int(10));           // Uses_ = 1,Weaks_ = 2,引用计数对象构造时,Uses_和Weaks_直接被初始化为1
    		wp = sp1;                                   // Uses_ = 1,Weaks_ = 2
    		shared_ptr<Int> sp2(sp1);                   // 左值引用拷贝构造,Uses_ = 2,Weaks_ = 2
    		{
    			shared_ptr<Int> sp3(sp1);               // 左值引用拷贝构造,Uses_ = 3,Weaks_ = 2
    			cout << wp.use_count() << endl;         // 3
    		} // sp3析构,Uses_ = 2,Weaks_ = 2
    	}     // sp2和sp1都析构,Uses_ = 0,Weaks_ = 1
    	if (!wp.expired()) {
    		cout << wp.use_count() << endl;             // Uses_ = 0,进入if
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Excel 多条件筛选 与 数据透视表 实现
    信息技术基础认知与实践-Python
    coding_v3
    Linux学习第19天:Linux并发与竞争实例: 没有规矩不成方圆
    壳聚糖修饰人血清白蛋白 Chitosan-HSA,根皮苷修饰人血清白蛋白(Phlorizin-HSA)
    java+springboot基于性别网上学习特征问卷调查及可视化系统
    Makefile 介绍
    Kitex源码阅读——脚手架代码是如何通过命令行生成的(二)
    Kubernetes(k8s) Web-UI界面(一):部署和访问仪表板(Dashboard)
    统计学中关于自由度的详细解释以及求平均值为什么消耗自由度1
  • 原文地址:https://blog.csdn.net/qq_42500831/article/details/126734941