码迷,mamicode.com
首页 > 编程语言 > 详细

C++11 智能指针

时间:2018-09-06 14:47:09      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:存在   智能指针   null   运行时   weak_ptr   isp   lex   使用   关系   

1、C++98的智能指针

技术分享图片

2、C++11的智能指针

智能指针本质是一个模板类

(1)三种智能指针

头文件 <memory>

unique_ptr 共享的智能指针

shared_ptr 独占的智能指针

weak_ptr 弱引用的智能指针

(2)explict关键字

C++11之后的智能指针的构造函数都有explict关键词修饰,表明它不能被隐式的类型转换。

shared_ptr<int> p1 = new int(1024);

//编译不过,因为等号左边是一个类对象,等号右边是一个int*的指针,因为有explict修饰,所以它不能被隐式的转换为shared_ptr<int>的类型

shared_ptr<int> p2(new int(1024)); //这种是直接采用了初始化的形式

shared_ptr<int> p3 = make_shared<int>(1024); //也可以用make_shared类

3、unique_ptr

持有对对象的独有权,同一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义、只有移动语义来实现)。

unique_ptr指针本身的生命周期:从unique_ptr指针创建时开始,直到离开作用域。离开作用域时,若其指向对象,则将其所指对象销毁(默认使用delete操作符,用户可指定其他操作)。

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

(1)类内部重载了*运算符,可以像指针那样访问所分配的堆内存

技术分享图片

(2)由于其独占性,不能与其他unique_ptr对象共享所指向的堆内存

技术分享图片

(3)up1只能通过move语义把内存指向的所有权给另一个对象up2,然后up1自己就失去所有权,此时程序运行中再访问up1时会出错。

技术分享图片

(4)使用类成员reset可以释放其指向的堆内存

up2释放之后,再对up1调用reset不会发生运行时错误

再对 *up2 访问的时候发生运行时错误

技术分享图片

4、shared_ptr

shared_ptr多个指针指向相同的对象。shared_ptr类内部使用引用计数,每一个拷贝的shared_ptr类对象都指向相同的内存。每拷贝一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

get函数获取原始指针,注意不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存。

注意避免循环引用,shared_ptr的一个最大的陷阱是循环引用,循环,循环引用会导致堆内存无法正确释放,导致内存泄漏。循环引用在weak_ptr中介绍。

(1)使用make_shared构造对象的区别

尽量使用 make_shared 和 make_unique(C++14才有),少用 new

make_shared 和 new 都是申请堆内存,make_shared 优点是效率高(申请内存次数少),避免内存泄漏,缺点是构造函数是保护或私有时,无法使用 make_shared,对象的内存可能无法及时回收。

方式1:

两次内存申请

技术分享图片

方式2:

一次内存申请

技术分享图片

(2)拷贝和赋值

拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1,当计数为0时,自动释放内存。后来指向的对象引用计数加1,指向后来的对象。

对比unique_ptr,把堆内存共享给其他对象sp2后,再访问sp1不会发生运行时错误,只是引用计数发生变化。

技术分享图片

技术分享图片

(3)对比unique_ptr,用reset释放sp1,访问sp2不会发生运行时错误

技术分享图片

5、weak_ptr

两个作用:记录对象是否存在,解决shared_ptr环形依赖问题

(1)记录对象是否存在

weak_ptr的对象是用来指向shared_ptr对象指向的内存,通过它的成员lock函数用来判断shared_ptr指向的数据内存是否还存在。

调用lock函数能够返回一个有效的shared_ptr指针(即shared_ptr指向的堆内存不是空的),如果引用计数为0,则返回空指针nullptr。

技术分享图片

(2)解决shared_ptr环形依赖问题

6、make_shared 的缺点

具体下面博客有说明:

https://blog.csdn.net/yagerfgcs/article/details/72886630

https://www.cnblogs.com/shengjianjun/p/3691928.html

 

参考博客:https://www.cnblogs.com/wxquare/p/4759020.html

https://blog.csdn.net/haolexiao/article/details/56773039

https://www.cnblogs.com/shengjianjun/p/3691928.html

C++11 智能指针

标签:存在   智能指针   null   运行时   weak_ptr   isp   lex   使用   关系   

原文地址:https://www.cnblogs.com/xiaozhihong/p/9597705.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!