std::shared_ptr和std::weak_ptr学习记录_std::shared_ptr weak -1-程序员宅基地

技术标签: 学习  c++  编程语言  蓝桥杯  

std::shard_ptr是智能指针,通过引用计数的方式共享对象的所有权,在引用计数为0时自动释放对象占用的内存。

int main(){
       int *p = new int(10);
       std::shared_ptr<int> a(p, [](int* p) {std::cout << "[deleter called]\n"; delete p;});
       std::cout << "p=" << p <<" a.get()=" << a.get() << " a=" << a << '\n';
       std::shared_ptr<int> b(a);
       std::cout << "b.use_count(): " << b.use_count() << '\n';
       std::cout << "b=" << b <<" b.get()=" << b.get() << " a=" << a << '\n';
       return 0;
}

运行信息:

p=0x798c20 a.get()=0x798c20 a=0x798c20

b.use_count(): 2

b=0x798c20 b.get()=0x798c20 a=0x798c20

通过打印信息,可以看出:p, a.get(), a, b, b.get()的值是一样的,是同一指针。

Note1:shared_ptr对象只能通过复制它们的值来共享所有权如果两个shared_ptr是从同一个(shared_ptr)指针构造(或生成)的,它们都将拥有该指针,但不共享它,当其中一个释放该指针(删除其管理对象),而让另一个指向无效位置时,会导致潜在的访问问题。即上面的例子中,应该通过std::shared_ptr<int> b(a)定义对象b,这样引用计数会增加;而不应该通过std::shared_ptr<int> b(p)来定义对象b

Note2: 循环引用导致的内存泄露问题。

#include <iostream>
#include <memory>

using namespace std;

class Abase;
class base {
public:
    base(string name): mName(name) {
        cout << "construct " << mName << endl;
    }

    virtual ~base() {
        cout << "deconstruct " << mName << endl;
    }

    void print() {
        cout << mName << " will print" << endl;
    }

public:
    string mName;
    shared_ptr<Abase> base_ptr;
};



class Abase {
public:
    Abase(string name):mName(name){
        cout << "construct " << mName << endl;
    }

    virtual ~Abase() {
        cout << "deconstruct " << mName << endl;
    }

    void print() {
        cout << mName << " will print" << endl;
    }

public:
    string mName;
    shared_ptr<base> Abase_ptr;
};



int main(int argc, char* argv[]) {
    {

        shared_ptr<Abase> A(new Abase("AAAAAAA"));
        shared_ptr<base> B(new base("BBBBBBB"));
        cout << B.use_count() << endl;
        cout << A.use_count() << endl;
        A->Abase_ptr = B;
        B->base_ptr = A;
        cout << B.use_count() << endl;
        cout << A.use_count() << endl;
    }

    return 0;

}

日志输出:

construct AAAAAAA

construct BBBBBBB

1

1

2

2

weak_ptr可以与shared_ptr对象共享指针,而不需要拥有它们,即不会增加引用计数从而解决了shared_ptr循环引用导致的内存泄露问题。上面的例子只要将Abasebase中的指针类型改成weak_ptr即可走到各自的析构函数中。

shared_ptr中的reset()函数:释放shared_ptr对象共同拥有的对象的所有权,即共享所有权的引用计数减一。

weak_ptr中的lock和expired函数比较重要,因为它本身不会增加引用计数,所以它指向的对象可能在它用的时候已经被释放了,所以在用之前需要使用expired函数来检测是否过期,如果expired() == true(函数expired()的功能等价于use_count()==0),表示实际对象已经不复存在了,这个时候调用lock返回的是一个指向null的shared_ptr对象;如果expired() == false,可以使用lock函数来获取其对应的shared_ptr对象(lock()会创建shared_ptr指针,在该指针的作用域范围内,会使引用次数+1,出作用域,引用次数-1)。

参考:

shared_ptr和weak_ptr的区别与联系_haodada1226的博客-程序员宅基地_shared_ptr weak_ptr

shared_ptr和weak_ptr_csdn_cjc的博客-程序员宅基地_shared_ptr weak_ptr

weak_ptr - C++ Reference

shared_ptr - C++ Reference

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41440739/article/details/124514885

智能推荐

七种最新群智能优化算法(NOA、LSO、SWO、ZOA、EVO、KOA、GRO)求解23个基准测试函数(含参考文献及MATLAB代码)-程序员宅基地

文章浏览阅读1w次,点赞17次,收藏193次。文件夹内包含七种优化算法(NOA、LSO、SWO、ZOA、EVO、KOA、GRO)求解23个测试函数的完整MATLAB代码,包含使用说明及参考文献,点击main.m即可运行,运行的结果图将自动保存到Picture文件夹内。_群智能优化算法

自定义OutputFormat的使用方法_自定义fileoutputformat-程序员宅基地

文章浏览阅读1k次。自定义OutputFormat使用为了实现控制最终文件的输出路径和输出格式,可以自定义OutputFormat.自定义OutFomat步骤1)A定义类继承FileOutputFormat,返回B自定义类2)B自定义类继承RecordWriter类,重写write()方法实现业务逻辑。先继承FileOutFormat,返回FRecordWriterpublic class FileterOutputFormat extends FileOutputFormat<Text, NullWrita_自定义fileoutputformat

【CesiumforUnreal插件】UE5 快速构建Cesium场景 快速入门!!!_cesium 在unreal中建筑物是白色-程序员宅基地

文章浏览阅读972次,点赞2次,收藏4次。文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎大家留言讨论。_cesium 在unreal中建筑物是白色

2023软件设计师中级备考经验分享(文中有资料链接分享)_2023软件设计师考试学习资料-程序员宅基地

文章浏览阅读2.6k次,点赞10次,收藏24次。上午题:推荐把软考通APP里的历年真题刷3-4遍,直接刷真题,然后背解析就行,没必要分章节练习。每次考试的真题会有几个往年的题,其他题目的话都是万变不离其宗,把历年真题刷几遍,背好解析。上午题几乎不是问题!下午题:推荐把近5年真题做一遍,把一个up的下午题真题解析课程听1遍就差不多了,2011年-2018年的真题解析课也得听一遍,考试的时候会有往年题出现。B站up主资料分享:【2023下半年中级软件设计师备考资料分享-哔哩哔哩】 https://b23.tv/C2kJjDm。我自己都没想到会这么好的成绩。_2023软件设计师考试学习资料

PS封装码流的解析_码流解析-程序员宅基地

文章浏览阅读4.2k次,点赞4次,收藏35次。1.解析PS码流的流程图2.获取数据2.1 读取源码文件2.2 冗余数据处理3.解析数据3.1 解析PS Header3.2 解析 PS system header(可有可无)3.3 解析PS system map(I帧才会有)案例:3.4 解析PES包3.5 保存裸数据3.6 保存时间戳3.7 保存帧类型..._码流解析

投影仪工作原理细说-程序员宅基地

文章浏览阅读2.7w次。项目中用到了投影系统,本科上课、开组会的时候对投影仪相当的不爽,感觉用着很麻烦。因为要调很多参数,色彩、位置balabala的。然并卵,一旦项目中采用了投影仪方案,呵呵,冤家路窄,好吧,解说一下自己对投影仪原理的认识~投影机的成像原理 投影机是一种用来放大显示图像的投影装置。 说到投影机显示图像的原理,基本上所有类型的投影

随便推点

Postman使用RSA加密字段及保存认证token_postman怎么进行rsa加密-程序员宅基地

文章浏览阅读468次,点赞9次,收藏8次。现有项目中认证使用OAuth2进行认证,为了安全密码用RSA加密,调试接口时需要先生成密码再调试,于是是否可以用Postman用RSA加密方式自动生成密码。研究发现Postman并没有自带RSA加密方式,现有的方案是使用第三方模块forge.js来实现加密,决定使用forge.js来实现RSA方式加密。来配置,aes或者rsa指加密方式,冒号后面是密码的明文。安装git、nodejs,具体安装方法不在本方中赘述,不会可以问度娘。至此,Postman使用RSA加密字段及保存认证token已经完成!_postman怎么进行rsa加密

【基于Arduino的嵌入式开发实例】基础实验(附带完整源码、效果展示):按键、蜂鸣器、温湿度传感器_dht11、液晶显示屏(输出基础字符、输出动态笑脸等表情//可结合温湿度传感器)-程序员宅基地

文章浏览阅读40次,点赞3次,收藏2次。分享几个有趣的基础实验,均是基于嵌入式开发平台Arduino,实验分别是:按键实验、蜂鸣器实验、温湿度传感器_dht11实验、液晶显示屏(输出基础字符、输出笑脸)的实验,均包含经过调试的可执行完整源代码,同时包含部分实验效果。注意:实验代码是一部分,另外重要的是还需要将引脚线连接完整(不出错),才能达到最佳的实验效果。此外,多多调试,也是必不可少的。

DashScope灵积模型服务 java testcase - 特色功能 模型监督学习_灵积模型声音训练java-程序员宅基地

文章浏览阅读923次,点赞16次,收藏15次。DashScope 测试 和模型比较代码 DashScope灵积模型服务建立在“模型即服务”(Model-as-a-Service,MaaS)的理念基础之上,围绕AI各领域模型,通过标准化的API提供包括模型推理、模型微调训练在内的多种模型服务。_灵积模型声音训练java

ffmpeg调整音频倍速_ffmpeg 音频变速-程序员宅基地

文章浏览阅读581次。ffmpeg命令行调整音频倍速,解释各个参数的含义。_ffmpeg 音频变速

MyBatis拦截器四种类型和自定义拦截器的使用流程_mybatis 拦截器-程序员宅基地

文章浏览阅读1.3k次,点赞35次,收藏17次。MyBatis拦截器四种类型和自定义拦截器的使用流程_mybatis 拦截器

Flutter基础_flutter appbar actions 布局中-程序员宅基地

文章浏览阅读2.4k次。Fluter基础Flutter环境搭建Android Studio开发环境搭建Flutter目录结构,入口函数以及基础组件目录结构文件夹 作用android android 平台相关代码ios ios 平台相关代码lib flutter 相关代码,我们主要编写的代 码就在这个文件夹test 用于存放测试代码pubspec.yaml 配置文件,一般存放一些第三方库的依 赖。入口函数void main_flutter appbar actions 布局中

推荐文章

热门文章

相关标签