文档章节

C++11智能指针

o
 osc_9sy7s563
发布于 2018/06/05 14:19
字数 1435
阅读 8
收藏 0
c++

行业解决方案、产品招募中!想赚钱就来传!>>>

前言

最近一段时间看代码,里面用到了C++的智能指针,发现自己竟然看不懂代码在表达什么意思,所以专门抽个时间恶补一下自己这方面欠缺的知识。
参考书籍《深入应用C++11:代码优化与工程级应用》

智能指针

C++11提供了3种智能指针:

  • std::shared_ptr、
  • std::uniqe_ptr
  • std::weak_ptr

使用时需要引用头文件#include <memory>

std::shared_ptr

std::share_ptr 使用引用计数,每一个shared_ptr的拷贝都指向相同的内存,最后一个shared_ptr析构的时候,内存才会释放。

1 share_ptr的基本用法

  • 智能指针初始化以及赋值

    不允许将普通指针赋值给智能指针,因为智能指针是一个类,而普通指针是一个值

  • 对于一个没有初始化的指针可以使用Reset来完成初始化。

  • 智能指针通过重载bool类型操作符,所以可以直接使用智能指针来判断是否为空

2 获取原始指针

使用p.get()可以获取智能指针的原始指针,cout也可以直接输出原始指针。

普通指针可以直接等于原始指针get()到的指针数据

3,指定删除器

智能指针初始化可以指定删除器

可以使用lambda表达式简化删除器的写法

当使用智能指针管理数组的时候,需要使用删除器,因为std::share_ptr不支持数组对象的释放

也可以使用默认的删除器,std::default_delete

在VC++中没法使用default_delete

std::shared_ptr<int> p(new int[10], std::default_delete<int[]>);

4. 使用shared_ptr注意事项

  1. 不要用一个原始指针初始化多个shared_ptr,原因在于,会造成二次销毁,如下所示:

    使用VC++2015测试发现,使用原始指针创建多个智能指针,会产生错误
    !
    使用智能指针初始化多个智能指针就不会存在问题,因为智能指针全部会纳入计数体系

  2. 不要在函数实参中创建shared_ptr。因为C++的函数参数的计算顺序在不同的编译器下是不同的。正确的做法是先创建好,然后再传入

//错误示范
function(shared_ptr<int>(new int), g());
  1. 通过shared_from_this()返回this指针。

    文中sp1返回的this指针作为裸指针使用,sp2拿到指针后成为与sp1无关的智能指针。两个智能指针在声明周期结束后,都会进行析构,结果形成了重复析构的操作

    智能指针不能直接返回this指针,需要通过派生std::enable_shared_from_this类,通过其方法shared_frome_this()来返回智能指针。

  2. 避免循环使用。智能指针的最大缺陷就是循环引用,循环引用会导致两个指针都不会被析构。

    当两个智能指针相互引用对方时,由于计数都为2,所以在结束时,没有达到析构的条件,所以都不会析构

std::unique_ptr

独占的智能指针,它不允许其他职能指针共享其内部的指针,不允许通过赋值,将一个unique_ptr赋值给另外一个unique_ptr

    unique_ptr<int> myPtr(new int(1));
    //下面的代码是错误的,无法通过=进行复制
    unique_ptr<int> myPtr2 = myPtr;

unique_ptr虽然不可以复制,但是可以转移,通过std::move来转移到其他的unique_ptr

可以看到unique_ptr通过move的方式,转移了指针的内容

    //unique_ptr只可以move不可以复制
    unique_ptr<MyType> other_p2 = other_p;

关于shared_ptr和uunique_ptr的使用场景,要根据实际应用来选择,如果只希望有一个智能指针管理资源或者管理数组就用unique_ptr,如果希望有多个只能指针管理同一个资源,就用shared_ptr

std::unique_ptr可以释放数组吗?

unique_ptr支持数组的释放,而shared_ptr不支持数组的释放

weak_ptr弱引用智能指针

  • 弱引用指针weak_ptr是用来监视shared_ptr的。主要是为了监视shared_ptr的声明周期。
  • 因为weak_ptr没有重载操作符*和->所以不能操作资源。
  • 它的构造不会增加引用计数,它的析构也不会减少引用计数,只是用来监测shared_ptr中管理的资源是否存在。
  • weak_ptr还可以用来返回this指针和解决循环引用的问题

weak_ptr基本用法

  • 通过use_cout()来获取当前观察资源的引用计数
  • 通过expired()来获取是否有效
  • 通过lock方法来获取所监视的shared_ptr,
    • lock之后可以访问指针的内容
    • weak_ptr可以通过直接赋值的方式来进行监视

通过智能指针管理第三方库分配的内存

智能指针适合于调用第三方接口库时使用,由于第三方库返回指针一般都是原始指针,所以使用智能指针可以在执行出错的情况下调用

void* p = GetHandle()->Create();
std::shared_ptr<void> sp(p, [this](void*p){GetHandle()->Release(p);});

总结

  • share_ptr的复制会增加计数,每次复制都会增加,只有最后一次释放的时候,才是真正的delete指针。
  • shared_ptr和uniqi_ptr如何选择:如果只有一个只能指针管理资源或者管理数组,可以使用uniq_ptr.如果希望多个智能指针管理同一个资源,可以用shared_ptr
  • weak_ptr是shared_ptr的助手,只是监视shared_ptr管理的资源是否被释放,本身不使用指针进行资源管理。用于解决share_ptr的循环引用和返回this指针的问题。




o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
【opencv】图形的绘制

1.矩形图像的绘制: 原函数:void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8,int shift=0) img就是需要绘制的图像 pt1 and pt......

其实我是兔子
2014/10/08
1.1K
1
跨平台 3D 游戏引擎--Castle Game Engine

Castle Game Engine 是一个用 Object Pascal 开发的跨平台 3D 游戏引擎。包含一个灵活的 3D 对象系统与开箱即用的水平,项目,智能生物等等。使用 X3D、VRML、Collada 和其他格式实现渲染和处理...

匿名
2013/02/05
2K
0
智能手机操作系统--Smartisan OS

Smartisan OS (俗称锤子操作系统),罗永浩创立的锤子科技推出的基于安卓(android)深度定制的系统。Smartisan释义:Smart+Artisan 组合创意词,意为智能机时代的精细工匠。...

匿名
2013/03/27
1.2W
1
Chrome页面自动刷新插件--smartF5

smartF5是一款chrome插件,用以实现监控页面资源,并自动刷新。 特别适合双屏情况下的DEMO开发,大大提高页面开发效率。 让你键盘上的F5键退休吧! 为什么选择smartF5 本插件具有以下特色: ...

YanisWang
2013/04/04
1.2W
0
开源的语义wiki引擎--Wikidsmart

Wikidsmart为融合是一个开源的语义wiki引擎使用zAgile语义框架和本体使智能集成与其他工具和应用程序。目前,Wikidsmart都启用了Atlassian融合,和其他wiki企业wiki计划将支持。...

匿名
2012/11/01
2.7K
0

没有更多内容

加载失败,请刷新页面

加载更多

认识Node

什么是Node? Node 是 JavaScript 的一种运行环境。可以使 JS 代码不依赖浏览器也可以执行。他俩的差异如下: 两个运行环境都包含了 ECMScript 。另一方面 JavaScript 包含了 BOM 和 DOM。 ...

长臂猿猴
29分钟前
13
0
正则表达式中的非捕获组是什么? - What is a non-capturing group in regular expressions?

问题: 非捕获组(即(?:) )如何在正则表达式中使用,它们有什么用? 解决方案: 参考一: https://stackoom.com/question/Ejkl/正则表达式中的非捕获组是什么 参考二: https://oldbug.net...

技术盛宴
30分钟前
6
0
他在国外演讲时说,学Python只要看答案做完这几十道题,就足够了

你想学Python?其实很简单,因为Python本身就是一门比较简单的编程语言。 你要做的也就是看着答案做完这几十道题就可以了,不管你是不是有编程基础,因为答案摆在那儿,你不可能不会做。 为什...

python小天
30分钟前
0
0
「2020最新」Spring最易学习教程 4—整合Mybatis 事务控制

0 复习 代理模式 代理模式,可以为目标类添加额外功能。 Spring 动态代理 定义目标类对象 定义额外功能,增强。实现Spring内置的接口 配置增强类 定义切入点 编织组装 增强类型 前置增强 Me...

鹿老师的Java笔记
50分钟前
21
0
OpenCV开发笔记(六十九):红胖子8分钟带你使用传统方法识别已知物体(图文并茂+浅显易懂+程序源码)

若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062 本文章博客地址:h...

红模仿_红胖子
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部