当前位置: 首页 > wzjs >正文

济南网站优化收费广东近期新闻

济南网站优化收费,广东近期新闻,嵊州网站制作,wordpress小程序github文章目录 智能指针智能指针的作用智能指针的拷贝auto_ptrC11的unique_ptrC11的shared_ptr 智能指针的使用智能指针的构造函数定制删除器make_shared 模拟实现shared_ptr引用计数赋值重载定制删除器 shared_ptr的循环引用问题weak_ptr的特点weak_ptr的唯一作用就是解决shared_pt…

文章目录

  • 智能指针
    • 智能指针的作用
    • 智能指针的拷贝
      • auto_ptr
      • C++11的unique_ptr
      • C++11的shared_ptr
    • 智能指针的使用
      • 智能指针的构造函数
      • 定制删除器
      • make_shared
    • 模拟实现shared_ptr
      • 引用计数
      • 赋值重载
      • 定制删除器
    • shared_ptr的循环引用问题
    • weak_ptr的特点
      • weak_ptr的唯一作用就是解决shared_ptr的循环引用问题
      • weak_ptr不支持RAII
      • weak_ptr虽然不会增加shared_ptr指向资源都引用计数,但是他依然可以查看那片资源的引用计数
      • 库里面的weak_prt它的成员函数lock()

智能指针

智能指针的作用

①RAII
通过RAII的方式防止内存泄露,特别是由于异常而导致的内存泄露,死锁,fd泄露等问题
在这里插入图片描述


RAII就是把申请资源的指针传给一个对象的构造函数,让这个对象里面的成员指针接收它
当这个对象的生命周期结束时,编译器就会自动调用析构函数
通过析构来去释放那个指针指向的资源

那它为什么能防止异常导致的资源泄漏呢?
因为
虽然发生了异常,但是异常去找try和匹配的catch语句的过程中,虽然不会再向后执行代码,但他寻找的过程中也是会结束函数栈桢的
这样的话,存储在函数栈桢中的对象的生命周期就会结束,就会自动调用析构

②模拟指针的行为
一般实现智能指针的时候会通过重载operator*()和operator—>()
来模拟指针的行为
和迭代器模拟指针的行为差不多



智能指针的拷贝

auto_ptr

C++98的库里面的auto_ptr实现的拷贝是:交换管理权


把一个auto_ptr a拷贝给另一个auto-ptr b的时候
a对它指向的资源的管理权就交给了b,然后a就会指向nullptr
之后就只能使用b去使用和释放资源了
非常坑

C++98的auto-ptr实现的不好,不推荐使用


C++11的unique_ptr

unique_ptr直接就不支持拷贝

所以如果确定要使用不会拷贝的智能指针,就可以使用unique_ptr


C++11的shared_ptr

shared_ptr采用了引用计数的方法实现拷贝

每一份交给shared_ptr的资源都会拥有一个引用计数
把一个shared_ptr a拷贝给另一个shared_ptr b的时候,a会让b会指向同一份资源,资源的引用计数就会++
只有当资源的引用计数为0时,资源才会被释放



智能指针的使用

智能指针的构造函数

参数1:指向资源的指针
一般都是我们把资源自己申请出来之后,直接把指向资源的指针传给智能指针
所以要给智能指针托管的对象要初始化的话,我们就自己在外面调用这个对象的构造函数初始化
然后再把对象的地址传给智能指针

参数2:定制删除器


定制删除器

因为智能指针指向不同类型的资源的时候释放的方式也是不同的

所以库里面的智能指针在析构函数的时候释放资源是:调用程序员自己写的定制删除器,进行资源的释放

定制删除器一般是仿函数/lambda等函数对象,函数类型是:void(T*ptr)
函数体就是对应资源的释放方式

不过比较奇怪的一点是,C++库里面的:
unique_ptr和shared_ptr接收定制删除器的位置是不同的
1.shared_ptr只支持在构造函数中接收定制删除器

2.unique_ptr则既支持在模板参数中接收,也支持在构造函数中接收
但是给构造函数接收的时候又比较麻烦,所以它通常是给模板参数接收

make_shared

make_shared是拥有可变模板参数的函数模板,使用必须显示实例化
它的工作原理是:
在函数体里面拿着参数接收到的参数包,new(从空间配置器中申请)并且初始化出一个对象,再创建一个shared_ptr接收这个对象

最后返回这个创建的shared_ptr

make_shared最大的作用就是减少内存碎片
因为make_shared它new的时候会把记录引用计数的空间和资源空间开在一起(连续)

使用make_shared的时候也要显示实例化
才能调用

在这里插入图片描述



模拟实现shared_ptr

引用计数

模拟实现shared_ptr最重要的就是实现它的引用计数的拷贝

shared_ptr的引用计数是存储在那里的呢?
是每一块资源都对应在堆上开辟一块4/8字节的空间存储计数的

为什么不存储在普通的成员变量里?
因为这样太独立了
因为这样的话每个shered_ptr对象都有一个自己的引用计数,看到的和修改的都不是同一个,这记个蛋的数?
根本就不知道另一个引用这块资源的shared_ptr什么时候析构什么时候拷贝构造

那为什么不存储在一个静态的成员变量里?
因为这样太共享了

因为静态的成员变量是整个类共有的

如果这一个类都只有一份指向的资源,那确实没问题

但是下面这种情况就不行
shared_ptr sp1(new int)
shared_ptr sp2(sp1)

shared_ptr sp3(new int)

这个时候静态成员变量确实正确可以记录sp1和sp2的指向的资源
但是当sp3构造再新构造出来的时候怎么去记录指向sp3的资源的指针数量呢?
一个静态成员没办法同时描述两个不同资源的引用计数口牙

因为每一块资源都要有自己对应的引用计数
所以只需要再给shared_ptr增加一个成员指针pcount,指向存储引用计数的空间就可以了,这样所有指向该资源的shared_ptr就都通过这个指针看到同一个引用计数了

又因为每一块新的资源都是在shared_ptr构造函数里接收到的
所以在构造函数为新资源开辟引用计数的空间


因为拷贝构造的时候,shared_ptr这个类不会接收新的资源
而是新智能指针指向旧资源
所以只需要引用计数++,新智能指针的资源和引用计数指针指向旧空间

析构的时候,就- -引用计数,减到零的时候再释放



赋值重载

注意点
①=的左操作数接收赋值之前
要先- -自己的引用计数,如果减到零,还要把自己指向的资源释放
然后再接受右操作数的资源和引用计数
再++右操作数的引用计数

②=的左右操作数指向的资源相同的时候,这个时候什么都不能干

因为
①既然都指向同一块资源,那也没必要赋值

②如果左右操作数的是同一个智能指针
并且它指向资源,只有它一个智能指针在指向

这个时候因为会先- -左值的引用计数,就一定会减到0
他就会把这个资源释放掉了,那这个时候再++也是野指针访问了


定制删除器

再创建一个function的成员变量,接收传给构造函数的定制删除器
在析构的时候就调用function对象。

顺便给这个function的对象一个缺省值:[ ](T*ptr){ delete ptr};
这样默认构造也能够正确的调用,并释放资源



shared_ptr的循环引用问题

循环引用会导致内存泄露

什么是循环引用?
循环引用就是
如果有两个(多个)的shared_ptr a和b分别指向了两个(多个)从堆区中申请的节点,设分别为x和y

而它们指向的两个new出来的节点内部,都有一个(多个)的shared_ptr的成员变量,设分别为px和py

此时如果两个(多个)节点里面的智能指针互相指向对方的节点就会内存泄露
因为为这两个(多个)new出来的节点计数的引用计数永远不可能为0

只要两个(多个)new出来的资源内部,还有一对(多对)shared_ptr互相指向对方节点,就一定会循环引用,内存泄露
那么两个(多个)节点对应的引用计数一定≥2
此时存储在节点外的指向节点智能指针,析构的时候,最多只能把引用计数减到1
而new出来的节点是不可能自己释放的

即:
a→x,b→y
px→y
py→x
且a,b,px,py的类型相同


在这里插入图片描述

如果他们里面没有一对及其以上的互相指向的智能指针
就不会出问题


在这里插入图片描述

解决方法
使用库里面的weak_ptr[弱指针]

即:把申请的两个(多个)节点里面,互相指向,对方节点,的智能智能shared_ptr换成弱指针weak_pte

因为
weak_ptr可以通过=和拷贝构造直接接收对应类型的shared_ptr
且这样子接收的时候
不会增加shared_ptr指向的资源的引用计数

所以
就不会出现引用计数永远不可能为0的情况了



weak_ptr的特点


weak_ptr的唯一作用就是解决shared_ptr的循环引用问题


weak_ptr不支持RAII

所以它并不能像其他的智能指针一样直接通过构造函数接收资源析构也不会自动释放资源

weak_ptr虽然不能直接通过构造函数接收资源
但是weak_ptr的赋值重载和拷贝构造的参数可以直接接收shared_ptr,去指向这个shared_ptr指向的资源

但是这样子接收的时候
不会增加shared_ptr指向的资源的引用计数


weak_ptr虽然不会增加shared_ptr指向资源都引用计数,但是他依然可以查看那片资源的引用计数

因为如果那片资源已经被shared_ptr释放了
但是有可能指向那片资源的weak_ptr的生命周期还没结束
所以weak_ptr可以查看它指向的资源的引用计数
这样用户就可以通过expired来知道它是否还有效


库里面的weak_prt它的成员函数lock()

的作用是:
创建一个指向weak_ptr指向的资源的shared_ptr并返回

这样就weak_ptr可以使用lock创建一个和和自己生命周期一样长的shared_ptr
这样就能保证在weak_ptr生命周期之内,它指向的资源也一定没有释放
因为至少有一个和他生命周期一样长的shared_ptr也指向这块资源

http://www.dtcms.com/wzjs/24906.html

相关文章:

  • 开县做网站百度关键词推广帝搜软件
  • 青岛网站建设服务器凡科建站官网免费注册
  • 购物网站建设模板下载域名状态查询工具
  • wordpress多说读者墙杭州优化公司在线留言
  • 浙江住房和城乡建设厅网站win10最强性能优化设置
  • 联系我们_网站制作公司网络公司的推广
  • 肇庆网站建设手机百度下载免费安装
  • 网络公司 营销型网站西安seo关键词排名优化
  • 沅江市住房和建设局网站软文代发
  • 好网站不私藏创建网址快捷方式
  • 绍兴模板建站代理社交网络的推广方法有哪些
  • 微信推广方法鼓楼网站seo搜索引擎优化
  • 嘟嘟浏览器灰色词seo排名
  • 做自己的网站难不难全网营销平台
  • 南川集团网站建设河南网站定制
  • 最好的开发网站建设百度天眼查公司
  • 专门搜索知乎内容的搜索引擎山东seo网页优化外包
  • 个人网站可以做导购吗中国十大网站有哪些
  • 苏州做企业网站有哪些百度云登陆首页
  • 外贸网站建设升上去在哪个网站可以免费做广告
  • 奉节做网站安徽seo推广公司
  • 弘泽建设集团网站电商网站策划
  • 北海做网站有哪家好标题优化怎么做
  • 宁波公司建网站哪家好软文世界
  • 在线做网站教程全部列表支持安卓浏览器软件下载
  • 一级域名网站如何申请什么是百度竞价排名服务
  • 用模板做企业网站推广文章的推广渠道
  • 电子商务网站建设含义推广下载app赚钱
  • 如何建立搜索功能的网站策划方案
  • 和网站合作有哪些活动可以做seo综合优化公司