温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

深度剖析智能指针

发布时间:2020-07-06 05:06:22 来源:网络 阅读:377 作者:下一个明天 栏目:编程语言


RALL:资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数中完成资源的分配和初始化,在析构函数中完成资源的清理。

首先来看这样一个例子:

深度剖析智能指针

此例子乍一看上去,new/delete匹配,并没有什么错。但就因为return的存在,使得Test()函数提前结束,并没有执行delete p。这就使得内存泄露。

内存泄露的危害:使得可用内存越来越少,下一次开辟可能不够,程序崩溃。

为解决此类问题,引入智能指针。

所谓的智能指针就是智能/自动化的管理指针所指向的动态资源的释放。

智能指针的行为类似于常规指针,重要的区别在于它负责自动释放所指向的对象。

智能指针也是模板,当我们创建一个智能指针时,需要提供指针可以指向的类型。

智能指针有:auto_ptr,scoped_ptr,shared_ptr,scoped_array,shared_array

1.auto_prt的模拟实现(以前)

深度剖析智能指针

深度剖析智能指针

注:以前的auto_ptr看起来已经实现的挺好的,多个指针指向同一块内存,并且释放的时候也正确

但是在实现的时候,会出现"野指针"。也就是所谓的"悬挂指针"。

深度剖析智能指针在析构函数中,只是对拥有管理权者进行了析构。在delete内存之后重置指针的方法只对这个指针有效,对其他任何指向(已释放的)内存的指针是没有作用的。所以会出现"野指针"。

为解决"野指针"问题,可以将管理权转交后,将以前的指针赋为NULL。也就是auto_ptr的现代写法。

auto_ptr的现代写法:

深度剖析智能指针

深度剖析智能指针

注:虽然此方法解决了"野指针"的问题,但是在拷贝构造和赋值后,只有一个指针有效。其他的都已为NULL,但有时候会对NULL指针进行引用,使得程序崩溃。


2.简单粗暴的scoped_ptr

scoped_ptr不允许拷贝构造和赋值,在C++11标准中叫unique_ptr

深度剖析智能指针

注:为了防拷贝和赋值

(1)只将拷贝构造和赋值函数声明不定义

(2)将拷贝构造和赋值函数声明为private或protected,防止别人搞破坏


3.允许拷贝和赋值的shared_ptr

shared_ptr是通过一个引用计数来记录该块空间被共享了几次,只有当计数器为0时才被释放。

深度剖析智能指针

深度剖析智能指针

4. 简单粗暴的scoped_array

scoped_array和scoped_ptr类似,是为了防拷贝和赋值。但是scoped_array是对数组来说的,因此在析构时要特别注意,应该使用delete[]来释放内存。

深度剖析智能指针

注:scoped_ptr是为了防拷贝和赋值。因此只将拷贝和赋值声明而不定义,并且将拷贝和赋值声明为private或者protected,防止他人搞破坏。


5.允许拷贝和赋值的shared_array

shared_array和shared_ptr类似。也是使用了一个引用计数。但是shared_array是对数组来说的。因此在析构时应使用delete[]。

深度剖析智能指针

深度剖析智能指针

6.现代版的shared_ptr看起来不错,但是会出现以下几个问题

(1)循环引用

(2)定置删除器


6.1循环引用

深度剖析智能指针

深度剖析智能指针

为了解决循环引用,应该使用弱指针weak_ptr(防止引用计数的增加)

深度剖析智能指针

注:所谓的weak_ptr就是用来服务shared_ptr。将一个weak_ptr绑定一个shared_ptr上不会改变shared_ptr的引用计数。


6.2 定置删除器

我们都只到shared_ptr只能释放new开辟出来的空间。而对于malloc开辟出来的空间,以及fopen打开的文件不能处理。为了能够处理各种情况,引入定置删除器。而定置删除器的实现是通过operator()即重载()来实现的。

深度剖析智能指针

深度剖析智能指针

深度剖析智能指针

深度剖析智能指针

测试结果:

深度剖析智能指针


注:任何情况下都不要使用auto_ptr。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI