IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++|项目开发—智能指针回顾 -> 正文阅读

[C++知识库]C++|项目开发—智能指针回顾

智能指针? ? ? ??

C++的智能指针:?auto_ptr, shared_ptr, weak_ptr, unique_ptr?,auto_ptr已经被c++11弃用,被更安全的shared_ptr所替代。

在C++中使用new关键字开辟的内存必须被手动delete掉,不然就会导致内存的泄漏,为了解决这种因为遗忘或者异常处理而导致内存泄漏的问题,我们就要用智能指针。智能指针的思想是在构建对象时获取我们资源的指针,接着控制对资源的访问使之在对象的生命周期内一直保持有效,在对象析构时释放指针对应的内存块。

一、auto_ptr被摒弃的原因:

1、auto_ptr在拷贝或者赋值过程中,直接剥夺原对象对内存的控制权,转交给新对象,然后再将原对象指针置为nullptr。实现了管理权转移。当我们再次去访问原对象时,程序就会报错。

2、当有两个auto_ptr指向同一个对象,当一个指针过期,另一个指针在过期就会出现两次析构一个对象,也会出现问题。

二、shared_ptr

? ? ? ? shared_ptr(重点):其一个共享所有权的智能指针,允许多个指针指向同一个对象。shared_ptr 利用引用计数的方式实现了对所管理的对象的所有权的分享,即允许多个 shared_ptr 共同管理同一个对象。

(a)当创建智能指针类的新对象时,初始化指针,并将引用计数设置为1;

(b)当能智能指针类对象作为另一个对象的副本时,拷贝构造函数复制副本的指向辅助类对象的指针,并增加辅助类对象对基础类对象的引用计数。

(c)使用赋值操作符对一个智能指针类对象进行赋值时,先使左操作数的引用计数减 1(指针已经指向别的地方),如果减1后引用计数为 0,则释放指针所指对象内存。然后增加右操作数所指对象的引用计数(此时操作数指向对象即右操作数指向对象);

(d)完成析构函数:调用析构函数时,析构函数先使引用计数减 1,如果减至 0 则 delete 对象。

(e)勿用一个原始指针初始化多个shared_ptr, 以造成二次释放同一内存。

例子:

     int?num?=?10;????shared_ptr<int>ptr1?=?make_shared<int>(num);????//拷贝????shared_ptr<int>ptr2(ptr1);????//?????int?num2?=?20;????int*?pb?=?&num;    //不允许直接将指针赋值给类????shared_ptr<int>ptrb?=?make_shared<int>(num2);    ptr2 = ptrb;//赋值????pb?=?ptrb.get();//获取原始指针
shared_ptr<T>?sptr;?//指向类型为T的空指针sptr.get();?返回sptr中保存的指针sptr.use_cout();??返回指针共享对象的智能指针数量make_shared<T>(args);?返回一个shared_ptr,指向动态分配类型为T的对象使用args初始化对象。
std::shared_ptr<int>?sptr?=?std::make_shared<int>(10);?引用计数为1//sp1是sp的拷贝,此操作会递增sptr指向对象的引用计数std::shared_ptr<int>?sp1(sptr);?std::shared_ptr<int>?sp?=?std::make_shared<int>(5);//给sptr赋值,使它指向另一个地址,此操作会递增sp指向对象的引用计数,//递减sptr原来指向对象的引用计数sptr?=?sp;??

缺陷:

shard_ptr 会产生一些问题:1、引用计数可能会引起线程安全问题;2、会产生循环引用的问题(循环引用需要weak_ptr和shard_ptr搭配解决)。

三、unique_ptr

unique_ptr 独占所管理的对象。无法复制到其他 unique_ptr,无法通过值传递到函数(即不能调用拷贝构造函数和赋值运算符重载函数),也无法用于需要副本的任何标准模板库 (STL)算法。

unique_ptr在生命周期内,可以改变智能指针所指对象,如创建智能指针时通过构造函数指定、通过reset方法重新指定、通过release方法释放所有权、通过移动语义转移所有权。

{        std::unique_ptr<int> uptr(new int(10));  //绑定动态对象        //std::unique_ptr<int> uptr2 = uptr;  //不能赋值????????//std::unique_ptr<int>?uptr2(uptr);??//不能拷贝        std::unique_ptr<int> uptr2 = std::move(uptr); //转移所有权????????uptr2.release();?//释放所有权,返回指针,并将uptr2置空????}//超过uptr的作用域,內存释放
std::unique_ptr<int> upMove = std::move(up); //转移所有权//u2被初始化为u1原来保存的指针,且u1置为空std::unique_ptr<int>?u2(u1.release());?u.reset():释放u指向的对象u.reset(q):如果提供了内置指针q,令u指向这个对象,否则将u置为空std::unique_ptr<int>?u(new?int(10));?//reset释放了u原来指向的内存,指向u1原来保存的指针,且将u1置为空u.reset(u1.release());?

四、weak_ptr

weak_ptr是一种弱类型(不单独使用,不具有普通指针的行为,无法重载operator*->),必须配合shard_ptr来使用,并用来解决循环引用问题

可以将shared_ptr的对象赋值给weak_ptr,并且这样并不会改变引用计数。weak_ptr主要有lock、swap、reset、expired、operator=、use_count几个函数。

例子来自:https://blog.csdn.net/K346K346/article/details/81478223

weak_ptr<T> w;     //创建空 weak_ptr,可以指向类型为 T 的对象weak_ptr<T> w(sp);  //与 shared_ptr 指向相同的对象,shared_ptr 引用计数不变。T必须能转换为 sp 指向的类型w=p;        //p 可以是 shared_ptr 或 weak_ptr,赋值后 w 与 p 共享对象w.reset();      //将 w 置空w.use_count();    //返回与 w 共享对象的 shared_ptr 的数量w.expired();    //若 w.use_count() 为 0,返回 true,否则返回 falsew.lock();??????//如果?expired()?为?true,返回一个空?shared_ptr,否则返回非空?shared_ptr
std::weak_ptr<T>?wp;?//空weak_ptr,可以指向类型为T的对象std::weak_ptr<int>?wp(new?int(5));?//使用weak_ptr对象构造?std::shared_ptr<int> sp = std::make_shared<int>(6);std::weak_ptr<int> wp(sp); // 使用shared_ptr对象构造//std::shared_ptr<int> sp = std::make_shared<int>(5);//shared_ptr的对象赋值给weak_ptrstd::weak_ptr<int> wp(sp);std::cout?<<?wp.use_count()?<<?std::endl;if(!wp.expired()){    std::shared_ptr<int> sp2 = wp.lock();????std::cout?<<?*sp2?<<?std::endl;

例子来自https://blog.csdn.net/oyb_lyj/article/details/81433323

?

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 01:23:14  更:2021-08-17 01:23:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 4:08:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码