【C++】智能指针——auto_ptr,unique_ptr,shared_ptr

devtools/2024/11/20 2:26:48/

目录

auto_ptr

unique_ptr

shared_ptr

并发问题

循环引用问题


个人主页:传送门——>东洛的克莱斯韦克

智能指针的原理:传送门——>智能指针的原理

auto_ptr

使用方法参考官方文档

传送门——>auto_ptr文档

auto_ptr并不是一个优秀的智能指针,它的设计理念是——管理权转移。如下代码示意

auto_ptr(auto_ptr<T>& sp):_ptr(sp._ptr){// 管理权转移sp._ptr = nullptr;}

旧的智能指针的会转移给新的智能指针,而旧的智能指针的会被置空。所以就有一个很严重的问题——如果对置空的智能指针做了加加减减等操作呢?如下代码示意

int main()
{std::auto_ptr<int> sp1(new int);std::auto_ptr<int> sp2(sp1); // 管理权转移//sp1悬空*sp2 = 10;cout << *sp2 << endl;cout << *sp1 << endl;return 0;
}

auto_ptr是一个失败设计,很多公司明确要求不能使用auto_ptr

unique_ptr

使用方法参考官方文档

传送门——>unique_ptr文档

unique_ptr智能指针的设计理念很简单——防拷贝。也就是说一份资源只能由一个unique_ptr管理,如下代码示意

unique_ptr(const unique_ptr<T>& sp) = delete;unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;

shared_ptr

使用方法参考官方文档

传送门——>shared_ptr文档

不同于unique_ptr,shared_ptr的允许多个智能指针管理同一份资源。shared_ptr采用引用计数的机制来判断一个资源是否允许被销毁

shared_ptr的引用计数是额外申请了空间(并没有在类的内部),它的设计是由一个指针指向一块空间,该空间存放计数。这种设计难免会有内存碎片的问题

代码示意

shared_ptr(T* ptr = nullptr):_ptr(ptr), _pRefCount(new int(1)) //额外开辟空间, _pmtx(new mutex){}

并发问题

引用计数本身是有并发问题的,关于线程,并发,锁相关知识可参考小编另一篇文章。

传送门——>线程,并发,锁

1.智能指针对象中引用计数是多个智能指针对象共享的,两个线程中智能指针的引用计数同时 ++或--,这个操作不是原子的,引用计数原来是1,++了两次,可能还是2.这样引用计数就错 乱了。会导致资源未释放或者程序崩溃的问题。所以只能指针中引用计数++、--是需要加锁 的,也就是说引用计数的操作是线程安全的。

2. 智能指针管理的对象存放在堆上,两个线程中同时去访问,会导致线程安全问题。

所以引用计数的加加减减操作是加锁的。如下代码示意

void Release(){_pmtx->lock();bool flag = false;if (--(*_pRefCount) == 0 && _ptr){cout << "delete:" << _ptr << endl;delete _ptr;delete _pRefCount;flag = true;}_pmtx->unlock();if (flag == true){delete _pmtx;}}void AddRef(){_pmtx->lock();++(*_pRefCount);_pmtx->unlock();}

循环引用问题

该问题是有类似于链表节点的结构引起的,当外部的智能指针都释放了,就拿不内部的智能指针,那么节点就不会释放

解决方案:在引用计数的场景下,把节点中的_prev和_next改成weak_ptr就可以了,weak_ptr不会增加引用计数,代码示意

struct ListNode
{int _data;weak_ptr<ListNode> _prev;weak_ptr<ListNode> _next;
};


http://www.ppmy.cn/devtools/104751.html

相关文章

split对大文件(tar/tar.gz)文件进行分片及合并

文章目录 1、tar文件指定大小分片2、合并分片文件并解压 1、tar文件指定大小分片 split -b 4000M -d -a 3 cm-11.tar.gz cm-11.tar.gz.使用split命令&#xff0c;-b 4000M 表示设置每个分割包的大小&#xff0c;单位还是可以k -d "参数指定生成的分割包后缀为数字的形式 …

Python 生成随机的国内 ip

示例代码&#xff1a; import randomdef generate_random_cn_ip():# 中国大陆IP范围start_ip "36.54.0.0"end_ip "123.255.255.254"# 将IP地址转换为整数start_ip_num int(start_ip.replace(".", ""))end_ip_num int(end_ip.rep…

如何防范ddos 攻击

防护DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一个复杂且多方面的任务&#xff0c;需要综合考虑网络架构、硬件设备、软件配置以及安全策略等多个方面。以下是一些主要的防护DDoS攻击的方法&#xff1a; 1. 流量清洗&#xff08;Traffic Scrubbing&#xff09; 定义…

.net dataexcel winform控件 更新 日志

增加 列宽度调整时动态显示列象素大小 更改列的宽度可以使用 column.Width属性进行修改

【无人机设计与控制】使用 Simulink 进行四轴飞行器/四旋翼飞行器仿真

摘要 本文介绍了如何使用Simulink进行四轴飞行器&#xff08;四旋翼&#xff09;仿真&#xff0c;通过建立详细的动力学模型和控制系统&#xff0c;实现对四旋翼无人机的姿态、位置和路径控制的精确仿真。该仿真环境不仅能够用于研究无人机的飞行控制性能&#xff0c;还可用于…

【MySQL】字节跳动MySQL连环40问(网图)

本文首发于 ❄️慕雪的寒舍 字节MySQL连环40问&#xff0c;网图 虽然感觉这玩意和字节跳动没关系&#xff0c;但是管他的&#xff1f;直接开始回答&#xff01; 1.MySQL中有哪几种锁&#xff1f; 会的不全&#xff0c;所以查的GPT MySQL中有多种类型的锁&#xff0c;主要包括以…

数据结构(邓俊辉)学习笔记】串 11——BM_BC算法:构造bc[]

画家策略 这里&#xff0c;我们给出 bc 表一种可能的构造算法。 我们知道 bc 表需要为字母表中的每一个字符准备一个表象&#xff0c;二者的长度相等。 因此&#xff0c;首先就要为它开辟出这样的一个空间&#xff0c;比如长度为256。 接下来&#xff0c;需要通过一趟循环遍历…

yolov8目标检测pyside6可视化图形界面+检测源码ui文件——用于计数统计

项目结构 YOLOv8模型加载&#xff1a;加载预训练的YOLOv8模型。PySide6 GUI&#xff1a;设计图形用户界面&#xff0c;用于显示检测结果和控制选项。摄像头/视频输入&#xff1a;从摄像头或视频文件读取图像帧。目标检测&#xff1a;使用YOLOv8模型对输入图像进行实时目标检测…