弱引用智能指针 std::weak_ptr 可以看做是 shared_ptr 的助手,它不管理 shared_ptr 内部的指针。std::weak_ptr 没有重载操作符 * 和 ->,因为它不共享指针,不能操作资源,所以它的构造不会增加引用计数,析构也不会减少引用计数,它的主要作用就是作为一个旁观者监视 shared_ptr 中管理的资源是否存在。

1.初始化

// 默认构造函数
constexpr weak_ptr() noexcept;
// 拷贝构造
weak_ptr (const weak_ptr& x) noexcept;
template <class U> weak_ptr (const weak_ptr<U>& x) noexcept;
// 通过shared_ptr对象构造
template <class U> weak_ptr (const shared_ptr<U>& x) noexcept;/*作者: 苏丙榅
链接: https://subingwen.cn/cpp/weak_ptr/#1-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95
来源: 爱编程的大丙*/

在 C++11 中,weak_ptr 的初始化可以通过以上提供的构造函数来完成初始化,具体使用方法如下:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> sp(new int);weak_ptr<int> wp1;weak_ptr<int> wp2(wp1);weak_ptr<int> wp3(sp);weak_ptr<int> wp4;wp4 = sp;weak_ptr<int> wp5;wp5 = wp3;return 0;
}/*作者: 苏丙榅
链接: https://subingwen.cn/cpp/weak_ptr/#1-1-%E5%88%9D%E5%A7%8B%E5%8C%96
来源: 爱编程的大丙*/
  • weak_ptr wp1; 构造了一个空 weak_ptr 对象

  • weak_ptr wp2(wp1); 通过一个空 weak_ptr 对象构造了另一个空 weak_ptr 对象

  • weak_ptr wp3(sp); 通过一个 shared_ptr 对象构造了一个可用的 weak_ptr 实例对象

  • wp4 = sp; 通过一个 shared_ptr 对象构造了一个可用的 weak_ptr 实例对象(这是一个隐式类型转换)

  • wp5 = wp3; 通过一个 weak_ptr 对象构造了一个可用的 weak_ptr 实例对象

其他常用方法

  • use_count()

通过调用 std::weak_ptr 类提供的 use_count() 方法可以获得当前所观测资源的引用计数,函数原型如下:

// 函数返回所监测的资源的引用计数
long int use_count() const noexcept;

修改一下上面的测试程序,添加打印资源引用计数的代码:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> sp(new int);weak_ptr<int> wp1;weak_ptr<int> wp2(wp1);weak_ptr<int> wp3(sp);weak_ptr<int> wp4;wp4 = sp;weak_ptr<int> wp5;wp5 = wp3;cout << "use_count: " << endl;cout << "wp1: " << wp1.use_count() << endl;cout << "wp2: " << wp2.use_count() << endl;cout << "wp3: " << wp3.use_count() << endl;cout << "wp4: " << wp4.use_count() << endl;cout << "wp5: " << wp5.use_count() << endl;return 0;
}

测试程序输出的结果为:

通过打印的结果可以知道,虽然弱引用智能指针 wp3、wp4、wp5 监测的资源是同一个,但是它的引用计数并没有发生任何的变化,也进一步证明了 weak_ptr只是监测资源,并不管理资源。

  • expired()

通过调用 std::weak_ptr 类提供的 expired() 方法来判断观测的资源是否已经被释放,函数原型如下:

// 返回true表示资源已经被释放, 返回false表示资源没有被释放
bool expired() const noexcept;

函数的使用方法如下:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> shared(new int(10));weak_ptr<int> weak(shared);cout << "1. weak " << (weak.expired() ? "is" : "is not") << " expired" << endl;shared.reset();cout << "2. weak " << (weak.expired() ? "is" : "is not") << " expired" << endl;return 0;
}

测试代码输出的结果:

weak_ptr 监测的就是 shared_ptr 管理的资源,当共享智能指针调用 shared.reset(); 之后管理的资源被释放,因此 weak.expired() 函数的结果返回 true,表示监测的资源已经不存在了。

  • lock()

通过调用 std::weak_ptr 类提供的 lock() 方法来获取管理所监测资源的 shared_ptr 对象,函数原型如下:

shared_ptr<element_type> lock() const noexcept;

函数的使用方法如下:

#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> sp1, sp2;weak_ptr<int> wp;sp1 = std::make_shared<int>(520);wp = sp1;sp2 = wp.lock();cout << "use_count: " << wp.use_count() << endl;sp1.reset();cout << "use_count: " << wp.use_count() << endl;sp1 = wp.lock();cout << "use_count: " << wp.use_count() << endl;cout << "*sp1: " << *sp1 << endl;cout << "*sp2: " << *sp2 << endl;return 0;
}

测试代码输出的结果为:

  • sp2 = wp.lock(); 通过调用 lock() 方法得到一个用于管理 weak_ptr
    对象所监测的资源的共享智能指针对象,使用这个对象初始化 sp2,此时所监测资源的引用计数为 2

  • sp1.reset(); 共享智能指针 sp1 被重置,weak_ptr 对象所监测的资源的引用计数减 1

  • sp1 = wp.lock();sp1 重新被初始化,并且管理的还是 weak_ptr 对象所监测的资源,因此引用计数加 1

  • 共享智能指针对象 sp1 和 sp2 管理的是同一块内存,因此最终打印的内存中的结果是相同的,都是 520


  • reset()

通过调用 std::weak_ptr 类提供的 reset() 方法来清空对象,使其不监测任何资源,函数原型如下:

void reset() noexcept;函数的使用是非常简单的,示例代码如下:#include <iostream>
#include <memory>
using namespace std;int main()
{shared_ptr<int> sp(new int(10));weak_ptr<int> wp(sp);cout << "1. wp " << (wp.expired() ? "is" : "is not") << " expired" << endl;wp.reset();cout << "2. wp " << (wp.expired() ? "is" : "is not") << " expired" << endl;return 0;
}

测试代码输出的结果为:

weak_ptr 对象 sp 被重置之后 wp.reset(); 变成了空对象,不再监测任何资源,因此 wp.expired() 返回 true

转载链接:

https://subingwen.cn/cpp/weak_ptr/#1-2-4-reset

[C++11]弱引用智能指针weak_ptr初始化和相关的操作函数相关推荐

  1. 9.C++弱引用智能指针weak_ptr的用处

    weak_ptr也是一个引用计数型智能指针,但是它不增加对象的引用计数,即弱引用.与之相对,shared_ptr是强引用,只要有一个指向对象的shared_ptr存在,该对象就不会析构,直到指向对象的 ...

  2. [C++11]shared_ptr共享智能指针的初始化与使用

    使用智能指针需要添加头文件: 代码如下: #include <memory> shared_ptr使用的注意事项: 1.不能使用一个原始地址初始化多个共享智能指针 2.函数不能返回管理了t ...

  3. c++ 智能指针_详解 C++ 11 中的智能指针

    C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置贬褒,手动分配内存与手动释放内 ...

  4. 智能指针weak_ptr

    weak_ptr这个指针天生一副小弟的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题. 相比于上一代的智能指针auto_ptr来说,新进老大 ...

  5. C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

    目录 1.引言 2.什么是智能指针? 3.在Visual Studio中查看智能指针的源码实现 4.独占式指针unique_ptr 4.1.查看unique_ptr的源码实现片段 4.2.为什么uni ...

  6. C++11 make_shared(智能指针初始化)

    智能指针可以智能地知道它是不是最后一个指向对象的指针,并且据此可以实现由对象的最后一个指针来决定对象的销毁. C++11提供两种智能指针(定义在<memory>): 1.shared_pt ...

  7. [C++11]独占的智能指针unique_ptr的初始化和使用

    std::unique_ptr 是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,可以通过它的构造函数初始化一个独占智能指针对象,但是不允许通过赋值将一个 unique_ptr 赋值给另 ...

  8. 智能指针——weak_ptr

    1. 开篇 正式介绍weak_ptr之前,先来复习一下shared_ptr 的一些知识. 我们知道shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维 ...

  9. c++11中的智能指针

    在C++11中有四种智能指针,auto_ptr,shared-ptr,unique_ptr和weak-ptr,其中auto_ptr有许多不足之处,在C++11中已经建议废弃使用. 1. shared_ ...

最新文章

  1. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors...
  2. ZOJ1027 Travelling Fee(DP+SPFA)
  3. socket.io.js的disconnect事件
  4. u8系统怎么连接服务器,用友U8 怎么连接远程服务器
  5. SQL Server 相关create操作语句
  6. mysql不能创建innodb类型表_MYSQL have_innodb DISABLED无法创建innodb类型的表
  7. python官网下载步骤-下载及安装Python详细步骤
  8. IDEA+MAVEN+testNG(reportNG)
  9. cf——Sasha and a Bit of Relax(dp,math)
  10. 全面解析抖音直播各类玩法;新人也能快速直播。
  11. libcurl入门之相关接口函数curl_easy_getinfo
  12. 华为“最青睐”的10所大学,有你的大学么?
  13. barefoot公司和Tofino芯片
  14. Periodic-table
  15. Mac 中composer的安装
  16. python斐波那契螺旋线怎么画向日葵心_斐波那契螺旋线的图形作法
  17. remind me of 2009
  18. 最大疯子树-树形dp+换根+二次扫描
  19. 高德地图获取所在城市POI数据
  20. 《拖延心理学》与时间管理

热门文章

  1. Android 整体设计及背后意义
  2. Android之android.os.NewWorkOnMainThreadException解决办法
  3. linux之openssl简单介绍
  4. 《看聊天记录都学不会Python到游戏实战?太菜了吧》(7)我用函数写了个特洛伊木马
  5. 【C语言简单说】十六:do...while循环
  6. php session缓存,扫盲:php session缓存至memcached中的方法
  7. 豆瓣评分9.4!这一部纪录片,探秘中国人迹罕至的未至之境!
  8. 把男朋友变成儿子你只需要一秒
  9. 怎么向小学生解释欧拉公式 e^(πi)+1=0?
  10. 10个经典的爆炸化学反应,个个都是你惹不起的“暴脾气”