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

目录

auto_ptr

unique_ptr

shared_ptr

并发问题

循环引用问题


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

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

auto_ptr

使用方法参考官方文档

传送门------>auto_ptr文档

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

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

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

cpp 复制代码
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管理,如下代码示意

cpp 复制代码
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的引用计数是额外申请了空间(并没有在类的内部),它的设计是由一个指针指向一块空间,该空间存放计数。这种设计难免会有内存碎片的问题

代码示意

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

并发问题

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

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

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

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

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

cpp 复制代码
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不会增加引用计数,代码示意

cpp 复制代码
struct ListNode
{
 int _data;
 weak_ptr<ListNode> _prev;
 weak_ptr<ListNode> _next;
};
相关推荐
A懿轩A25 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
机器视觉知识推荐、就业指导30 分钟前
C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
c++
半盏茶香30 分钟前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J1 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB1 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
Ronin3051 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工2 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白2 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
PieroPc3 小时前
Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印
开发语言·python·excel