音视频学习笔记——C++智能指针

C++智能指针介绍

  • 智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。
  • C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在==堆上分配。当新增一个时引用计数加1,当过期时引用计数减1。只有引用计数为0时,智能指针才会自动释放引用的内存资源。
  • shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。

二、为什么要使用智能指针

智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。
使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域时,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。

三、三种智能指针

C++11 中引入了智能指针,它利用了一种叫做 RAII(资源获取即初始化)的技术将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。这使得智能指针实质是一个对象,行为表现的却像一个指针。智能指针主要分为shared_ptr unique_ptr weak_ptr 三种,使用时需要引用头文件<memory>
C++11 中shared_ptr 和weak_ptr 都是参考boost 库实现的。

3.1 unique_ptr

unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象。采用所有权模式。
当程序试图将一个unique_ptr赋值给另一个时,如果源unique_ptr是个临时右值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做,比如:

	unique_ptr<string> pu1(new string ("hello world"));unique_ptr<string> pu2;pu2 = pu1; // #1 不允许unique_ptr<string> pu3;pu3 = unique_ptr<string>(new string ("You")); // #2 允许

3.2 shared_ptr

shared_ptr实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。
使用计数机制表明资源被几个指针共享。可以通过成员函数use_count()来查看资源的所有者个数。
成员函数:

use_count :返回引用计数的个数
unique :返回是否是独占所有权(use_count 为 1)
swap :交换两个hared_ptr 对象(即交换所拥有的对象)
reset :放弃内部对象的所有权或拥有对象的变更, 会引起原有对象的引用计数的减少
get :返回内部对象(指针), 由于已经重载了()方法, 因此和直接使用对象是一样的

例子:

	#include <iostream>#include "string"using namespace std;int main(){string *s1 = new string("s3");shared_ptr<string> ps1(s1);shared_ptr<string> ps2;ps2 = ps1;cout << ps1.use_count() << endl; //2cout << ps2.use_count() << endl; //2,ps2和ps1共用cout << ps1.unique() << endl; //0string* s3 = new string("s3");shared_ptr<string> ps3(s3);cout << (ps1.get()) << endl; //033AEB48cout << ps3.get() << endl; //033B2C50swap(ps1, ps3); //交换所拥cout << (ps1.get()) << endl; //033B2C50cout << ps3.get() << endl; //033AEB48cout << ps3.use_count() << endl; //2 ps3和ps1交换所拥有的对象cout << ps1.use_count() << endl; //1  cout << ps2.use_count() << endl; //2ps2 = ps1;cout << ps1.use_count() << endl; //2cout << ps2.use_count() << endl; //2ps1.reset(); //放弃ps1的拥有权,引用计数的减少cout << ps1.use_count() << endl; //0cout << ps2.use_count() << endl; //1}

运行结果:
在这里插入图片描述
share_ptr智能指针也是会发生内存泄露
当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏。这种情况需要通过智能指针weak_ptr解决。

3.3 weak_ptr

weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个shared_ptr管理的对象。进行该对象的内存管理的是那个强引用的shared_ptrweak_ptr只是提供了对管理对象的一个访问手段
设计目的:为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 只能从一个 shared_ptr 或另一个weak_ptr对象构造, 其构造和析构不会引起引用记数的增加或减少
weak_ptr是用来解决shared_ptr相互引用时的死锁问题。是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr

weak_ptr 没有重载*->但可以使用lock 获得一个可用的 shared_ptr 对象
expired 用于检测所管理的对象是否已经释放, 如果已经释放, 返回 true; 否则返回false
lock 用于获取所管理的对象的强引用(shared_ptr). 如果 expiredtrue, 返回一个空的shared_ptr; 否则返回一个 shared_ptr, 其内部对象指向与 weak_ptr 相同.
weak_ptr常用操作

	weak_ptr<T> w; // 空weak_ptr可以指向类型为T的对象weak_ptr<T> w(shared_ptr p); // 与p指向相同对象的weak_ptr, T必须能转换为sp指向w = p; // p可以是shared_ptr或者weak_ptr,赋值后w和p共享对象w.reset(); // weak_ptr置为空w.use_count(); // 与w共享对象的shared_ptr的计数w.expired(); // w.use_count()为0则返回true,否则返回falsew.lock(); // w.expired()为true,返回空的shared_ptr;否则返回指向w的shared_ptr

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电梯机房秀

每天乘坐电梯&#xff0c;您见过电梯的机房吗&#xff1f;来&#xff0c;跟着小伍去看看吧。Lets go&#xff01; 电梯还能节能呢&#xff0c;您知道么&#xff1f;正好&#xff0c;小伍一块带您看看电梯节能装置(●◡●) 目前电梯节能装置已广泛应用于三菱、富士、日立、奥的斯…

IBM:《2024年消费者调研:无处不在的人工智能彻底变革零售业》

1月17日&#xff0c;IBM商业价值研究院最近发布了第三份两年一度的消费者调研报告。 这项名为《无处不在的人工智能彻底改变零售业&#xff1a;客户不会等待》的报告&#xff0c;对包含中国在内的全球近20000名消费者进行了调研&#xff0c;相关结果反映了消费者对零售体验的普…

(黑马出品_07)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_07&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术分布式搜索 今日目标1.数据聚合1.1.聚合的种类1.2.DSL实现聚合1.2.1.Bucket聚合语法1.2.2.聚合结果排序1.2.3.限定聚合范围1.2.4.Metric聚合语法1.2.5.小…

Figure 公司的Figure 01人形机器人

文章目录 Figure 公司管理层成员 人工智能驱动的积极未来路线图使命公司现在可能性解决方案我们该怎么做结论 Figure 公司 Figure 公司是一家人工智能科技公司&#xff0c;总部位于美国旧金山。该公司专注于开发人形机器人和相关技术&#xff0c;旨在为用户提供与人工智能交互…

抖音开放平台第三方开发,实现代小程序备案申请

大家好&#xff0c;我是小悟 抖音小程序备案整体流程总共分为五个环节&#xff1a;备案信息填写、平台初审、工信部短信核验、通管局审核和备案成功。 服务商可以代小程序发起备案申请。在申请小程序备案之前&#xff0c;需要确保小程序基本信息已填写完成、小程序至少存在一个…

【Go语言】Go语言中的函数

Go语言中的函数 Go语言中&#xff0c;函数主要有三种类型&#xff1a; 普通函数 匿名函数&#xff08;闭包&#xff09; 类方法 1 函数定义 Go语言函数的基本组成包括&#xff1a;关键字func、函数名、参数列表、返回值、函数体和返回语句。Go语言是强类型语言&#xff0…

普林斯顿算法讲义(四)

原文&#xff1a;普林斯顿大学算法课程 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 6.1 事件驱动模拟 原文&#xff1a;algs4.cs.princeton.edu/61event 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 本章节正在建设中。 根据弹性碰撞的法则使用事件驱动…

C语言指针与数组(不适合初学者版):一篇文章带你深入了解指针与数组!

&#x1f388;个人主页&#xff1a;JAMES别扣了 &#x1f495;在校大学生一枚。对IT有着极其浓厚的兴趣 ✨系列专栏目前为C语言初阶、后续会更新c语言的学习方法以及c题目分享. &#x1f60d;希望我的文章对大家有着不一样的帮助&#xff0c;欢迎大家关注我&#xff0c;我也会回…

Dev Studio 安装与使用

目录 一、DevEco Studio 下载 二、DevEco Studio 诊断开发环境 2.1 配置NPM代理 2.2 ohpm 报错 三、启用中文化插件 四、构建第一个ArkTS应用&#xff08;Stage模型&#xff09; 4.1 创建ArkTS工程 4.2 ArkTS工程目录结构&#xff08;Stage模型&#xff09; 4.2 预览项…

TikTok美区再现爆款!“龙蛋”畅销海外!仅一周狂卖近40万美金

当小杨哥、东方甄选开始相继进军TikTok海外电商平台&#xff0c;新一轮的境外风云即将上演... TikTok作为短视频领域的翘楚&#xff0c;其病毒式营销手段让无数产品迅速走红&#xff0c;卖到断货在海外市场也是屡见不鲜&#xff01; 近日&#xff0c;一款独特的 3D 打印龙蛋玩…

WOA-GRU多输入回归预测 | 鲸鱼优化算法-门控循环单元神经网络 | Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&…

(转)已有 vue2 环境下安装 vue3 和vue2并新项目构建

vue2 全局安装过&#xff0c;废话不多说&#xff0c;直接装 vue3 吧 安装 vue3.X 不再需要安装 vue/cli3 的脚手架&#xff0c;而是通过官方推荐的 Vite 开发构建工具快速搭建&#xff0c;具体可查看官方文档 https://vue3js.cn/docs/zh/guide/installation.html#%E5%91%BD%E4…