weak_ptr 智能指针的使用

news2024/11/27 12:37:37

目录

一,weak_ptr 变量的定义

二,expired() 成员函数

三,lock() 成员函数

四,use_count() 成员函数

五,为什么要用 weak_ptr


一,weak_ptr 变量的定义

weak_ptr 对象的构造有3种方法:

1,构造空对象,如 std::weak_ptr<CTest> weakPtr;

2,拷贝构造,如 std::weak_ptr<CTest> weakPtr2(weakPtr);

3,用shared_ptr 对象进行初始化,如

std::shared_ptr<CTest> ptr = std::make_shared<CTest>();

std::weak_ptr<CTest> weakPtr3(ptr);

#include <stdio.h>
#include <stdlib.h>
#include <memory>

class CTest
{
public:
    CTest(): mValue(100)
    {
        printf("constructor\n");
    }

    ~CTest() 
    {
        printf("destructor\n");
    }
    
    int getValue()
    {
        return mValue;
    }
private:
    int mValue;
};

int main()
{
    std::weak_ptr<CTest> weakPtr;
    std::weak_ptr<CTest> weakPtr2(weakPtr);
	std::shared_ptr<CTest> ptr = std::make_shared<CTest>();
    std::weak_ptr<CTest> weakPtr3(ptr);

    int value = ptr->getValue();
    printf("value = %d, use_count = %d\n", value, ptr.use_count());

    value = (weakPtr3.lock())->getValue();
    printf("value = %d\n", value);

    ptr.reset();
    auto ptr2 = weakPtr3.lock();
    if(ptr2 == nullptr)
    {
        printf("weakPtr3.lock() = nullptr\n");
        return 0;
    }
    value = ptr2->getValue();
    return 0;
}

二,expired() 成员函数

bool expired() const noexcept; 函数返回 weak_ptr 对象是否是空的,或是它所属的所有者组中不再有shared_ptr。此函数与 use_count() == 0 意义相同。

#include <stdio.h>
#include <stdlib.h>
#include <memory>

class CTest
{
public:
CTest(): mValue(100)
{
	printf("constructor\n");
}

~CTest() 
{
	printf("destructor\n");
}

int getValue()
{
	return mValue;
}
private:
	int mValue;
};

int main()
{
	std::weak_ptr<CTest> weakPtr;
	std::weak_ptr<CTest> weakPtr2(weakPtr);
	std::shared_ptr<CTest> ptr = std::make_shared<CTest>();
	std::weak_ptr<CTest> weakPtr3(ptr);

	if(weakPtr.expired())
	{
		printf("weakPtr is empty!\n");
	}

	if(weakPtr2.expired())
	{
		printf("weakPtr2 is empty!\n");
	}

	if(weakPtr3.expired())
	{
		printf("weakPtr3 is empty!\n");
	}

	return 0;
}

我们可以看到源码是这样的:

三,lock() 成员函数

shared_ptr<element_type> lock() const noexcept; 函数返回一个shared_ptr,其中包含weak_ptr对象在未过期时保留的信息。如果 weak_ptr 对象已过期(包括它是否为空),该函数将返回一个空的shared_ptr(就像默认构造的一样)。

#include <stdio.h>
#include <stdlib.h>
#include <memory>

class CTest
{
public:
    CTest(): mValue(100)
    {
        printf("constructor\n");
    }

    ~CTest() 
    {
        printf("destructor\n");
    }
    
    int getValue()
    {
        return mValue;
    }
private:
    int mValue;
};

int main()
{
    std::weak_ptr<CTest> weakPtr;
    std::weak_ptr<CTest> weakPtr2(weakPtr);
    std::shared_ptr<CTest> ptr = std::make_shared<CTest>();
    std::weak_ptr<CTest> weakPtr3(ptr);

	std::shared_ptr<CTest> lck;
	lck = weakPtr.lock();
	if(lck == nullptr)
	{
		printf("weakPtr is empty!\n");
	}

	if(!weakPtr2.lock())
	{
		printf("weakPtr2 is empty!\n");
	}

	std::shared_ptr<CTest> test;
	if((test = weakPtr3.lock()) != nullptr)
	{
		printf("weakPtr3 is not empty! value = %d\n", test->getValue());

	}

    return 0;
}

在使用 lock() 函数时,可以判断其是否为nullptr。当用 gdb 查看时可以看到:lck=weakPtr.lock()后,lck 就是 0。 

我们可以看源码 lock() 函数是怎样实现的:

 

可以看到当对象过期时,构造了一个空的 shared_ptr<>对象进行返回,而这个空对象它的初始化值是这样的:

 

 

_M_ptr 是模板参数类型的指针,它指向的就是要管理的对象。而 _M_refcount  是管理引用计数的。所以一个空的 shared_ptr<> 并不管理任何对象,就不能当作对象指针来用了。但 use_count() 还是可以用的,用 lck.use_count() == 0 进行判断:

 

这里可能会有人疑问:lck 都是nullptr 了,怎么还能调用 use_count() 呢?这样调用不会崩溃吗?这个就要理解类与对象的关系了。可以看源码:

 

 

四,use_count() 成员函数

weak_ptr 里有两个计数,一个是 _M_use_count 管理对象的引用计数,一个是 _M_weak_count 是不是用于它本身的析构用的,还没研究。weak_ptr 的基类:

      _Tp*	 	 _M_ptr;         // Contained pointer.
      __weak_count<_Lp>  _M_refcount;    // Reference counter.
  template<_Lock_policy _Lp>
    class __weak_count
    {
    public:
      constexpr __weak_count() noexcept : _M_pi(0)
      { }

      __weak_count(const __shared_count<_Lp>& __r) noexcept
      : _M_pi(__r._M_pi)
      {
	if (_M_pi != 0)
	  _M_pi->_M_weak_add_ref();
      }

 __weak_count<_Lp> 模板类有一个成员 _M_pi, 其类型为 _Sp_counted_base<_Lp>*  _M_pi;

 _Sp_counted_base<_Lp> 就包含上述的两个计数。use_count() 函数调用的是_M_refcount._M_get_use_count(); 

五,为什么要用 weak_ptr

1,解决shared_ptr 循环引用的问题。这个网上也有很多例子

2,在不延长shared_ptr 管理对象生命周期的情况下,探知这个对象是否已经无效。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础综合案例-数据可视化(折线图)

今天给大家带来的是Python综合实战开发的数据可视化操作 通过python实现对数据的分析、可视化 数据来源: 系统开发环境&#xff1a; 操作系统&#xff1a;win11 Python解释器版本&#xff1a;python3.10 开发工具&#xff1a;Pychram Python内置模块&#xff1a;pyecharts 1…

HarmonyOS/OpenHarmony应用开发-Stage模型应用/组件级配置

在开发应用时&#xff0c;需要配置应用的一些标签&#xff0c;例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。图标和标签通常一起配置&#xff0c;可以分为应用图标、应用标签和入口图标、入口标签&#xff0c;分别对应app.json5配置文件…

二进制算术运算

当两个数码表示数量大小时&#xff0c;可以进行加减乘除等算术运算。 一&#xff1a;两数绝对值之间的运算 加法运算&#xff1a; 二进制的每一位只有0和1两个数&#xff0c;低位向高位的进位关系是“逢二进一”&#xff0c;所以中的每一位的运算规则为&#xff1a; 减法运算&…

【无标题】企业数字化转型需要什么样的生产力工具?

前言 企业的数字化转型是一个很大的话题&#xff0c;从宏观到微观&#xff0c;涉及到目标、战略、方案、路径、计划、组织、流程等方方面面。我们今天聊一个非常落地非常具体的问题——企业数字化转型需要什么样的生产力工具&#xff1f; 需要哪些类型的生产力工具&#xff1…

论文摘要写什么内容

一、引言 论文摘要是我们在学术研究领域当中最常见的一种形式&#xff0c;它扮演着关键的角色&#xff0c;为研究者在学术圈子中传播自己思想提供了重要途径。然而&#xff0c;如何编写一份既简洁而易读&#xff0c;又充满深度和洞察的摘要呢&#xff1f;这篇文章将提供一些基…

Scala特证/特质【6.7 特质(Trait)】

Scala特证/特质【6.7 特质&#xff08;Trait&#xff09;】 6.7 特质&#xff08;Trait&#xff09;Java 的接口接口的作用抽象类的作用 6.7.1 特质声明6.7.2 特质基本语法6.7.3 特质叠加6.7.4 特质叠加执行顺序6.7.5 特质自身类型6.7.6 特质和抽象类的区别 &#xff08;任意内…

Lua学习笔记:面向对象的实现

前言 本篇在讲什么 Lua中的面向对象的实现 本篇适合什么 适合初学Lua的小白 本篇需要什么 对Lua语法有简单认知 依赖Sublime Text编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &…

MySQL数据库基础(三):多表查询,子查询,开窗函数

十一、多表查询&#xff08;重点、难点&#xff09; 表与表之间的关系 在SQL语句中&#xff0c;数据表与数据表之间&#xff0c;如果存在关系&#xff0c;一般一共有3种情况&#xff1a; ① 一对一关系&#xff08;高级&#xff09; 比如有A、B两张表&#xff0c;A表中的每一…

多肽试剂:143120-27-8,Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide

试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a; 环肽试剂Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide&#xff0c;陕西新研博美生物科技有限公司多肽合成、定制多肽、同位素标记肽、人工胰岛素、磷酸肽、生物素…

Python split()函数使用详解,Python分割字符串

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 split 1、不指定分隔符2、分隔符的类型3、指定分隔次数4、分隔的结果 split() 可…

你真的不想知道怎么用ai绘画图片生成图片吗?

亲爱的二次元迷们&#xff0c;你是否曾经梦想过能够画出自己心中的二次元角色&#xff0c;让他们跃然纸上、生动活泼地展现在世人面前&#xff1f;但是&#xff0c;面对空白的画板和一支笔&#xff0c;我们有时会感到无从下手&#xff0c;毫无艺术细胞可言。不要失望&#xff0…

Dlib —— 对视频流进行人脸识别(附C++部分源码、完整源码下载)

照片效果 视频效果 注意&#xff1a;Dlib检测人脸在Release版耗时与CPU有关,本人I7 10代约100ms左右&#xff0c;这里本人将人脸检测用Yolov5对人脸简单抠图训练后 使用yolov5推理检测人脸&#xff0c;之后将检测到的人脸输入给Dlib做特征&#xff0c;发现人脸特征部分耗时也较…

基础实验篇 | uORB消息读写与自定义实验(一)

导读 uORB是PX4/Pixhawk系统中非常重要且关键的模块之一&#xff0c;是用于无人机模块间通信的协议机制。本篇将详细介绍uORB并详细拆解uORB消息读写与自定义实验&#xff08;一&#xff09;。 基础实验篇 | uORB消息读写与自定义实验(一) ect Request Broker&#xff0c;微对…

7、动手学深度学习——卷积神经网络:基础部件+LeNet

1、图像卷积 1. 互相关运算 严格来说&#xff0c;卷积层是个错误的叫法&#xff0c;因为它所表达的运算其实是互相关运算&#xff08;cross-correlation&#xff09;&#xff0c;而不是卷积运算。在卷积层中&#xff0c;输入张量和核张量通过(互相关运算)产生输出张量。 首先…

python 中禁用 SettingWithCopyWarning

最近代码中出现了这个warn&#xff0c;但是我确信我已经把所有的df赋值都改成loc了&#xff0c;依旧会出现&#xff0c;只有把这个warn禁了。 import pandas as pd import warnings# 禁用 SettingWithCopyWarning 警告 warnings.filterwarnings("ignore", categorypd…

闲人闲谈PS之四十三——标准程序的陷阱

惯例闲话&#xff1a;7月&#xff0c;闲人家乡的水蜜桃成熟了&#xff0c;闲人很喜欢吃桃子&#xff0c;可惜经常出门在外&#xff0c;经常错过了水果最好的季节&#xff0c;这次委托家人邮寄了几箱&#xff0c;果然还是家乡的桃子好吃。回顾这几年&#xff0c;错过了不仅仅是水…

数据库sql 根据身份证计算年龄段mysql、oracle

数据库sql根据身份证计算年龄段 mysql: SELECTage,count(*) numFROM(SELECTCASEWHEN TIMESTAMPDIFF(YEAR,DATE(substring(id_card,7,8)),CURDATE())<35 THEN 35岁以下WHEN TIMESTAMPDIFF(YEAR,DATE(substring(id_card,7,8)),CURDATE()) > 35AND TIMESTAMPDIFF(YEAR,DATE…

deque容器语法

文章目录 deque容器deque容器基本概念功能&#xff1a;deque 的实现细节deque与vector底层区别&#xff1a; deque构造函数功能描述&#xff1a;函数原型&#xff1a; deque元素访问deque赋值操作功能描述&#xff1a;函数原型&#xff1a; deque大小操作功能描述&#xff1a;函…

哪些期货公司招居间人,期货居间人的红利期时代已过,该何去何从

2021年9月10日&#xff0c;中国期货业协会发布了关于发布《期货公司居间人管理办法 (试行)》的通知&#xff0c;《期货公司居间人管理办法(试行)》正式出台。 根据通知&#xff0c;期货公司仅能与经有关金融监管部门批准设立的证券公司等金融机构开展居间合作。现在的法人居间绝…

【stable-diffuision-webui】controlnet制作动漫二维码(丐版)

主要参考 原作者的博文&#xff1a;AI生成可扫码图像 — 新 ControlNet 模型展示 光照生成模型C站说明&#xff1a;https://civitai.com/models/80536/lighting-based-picture-control-controlnet 扩展阅读&#xff1a;https://aigc.ioclab.com/sd-showcase/light_controlnet.…