vs2019 c++20 规范的 STL 库的智能指针 shared、unique 、weak 、auto 及 make_** 函数的源码注释汇总,和几个结论

智能指针的源码都在 《memory》 头文件中。因为头文件太长,再者本次整理是基于以前的零散的模板分析。故相当于抽取了该头文件中关于智能指针的源码进行分析,注释。

(1 探讨一)当独占指针指向数组时,其默认的删除器是哪个?相关模板的定义轮廓如下:

在这里插入图片描述

我们要分析、猜测编译器在泛型推导时是如何确定模板参数的类型的。先给出一段源码,如下:

在这里插入图片描述

测试如下:

在这里插入图片描述

以及:

在这里插入图片描述
以及:

在这里插入图片描述

STL 库代码肯定是不会错的。可以得出结论啊: unique_ptr 声明时的模板参数 _Ty 的含义不同于模板定义时的模板参数 _Ty, 模板声明时的删除器的默认值是对第一个模板实参的整体取 default_delete<_Ty[]> ,所以选择了正确的删除器模板。

(2 探讨二) 独占指针可以指向数组,对其成员函数 reset 的形参,应该提供数组指针,而不是普通指针。源码摘抄如下:

在这里插入图片描述

增加一些打印语句:

在这里插入图片描述

以及:

在这里插入图片描述

但又测试了一下:

在这里插入图片描述

(3 探讨三) 独占指针的内存模型。独占指针的构造还是比较简单的,因为不需要考虑资源共享,独占指针其实就是对裸指针的封装。摘抄的源代码如下:

在这里插入图片描述

(4 探讨四) 对 make_unique 函数的形参,若创建指向数组的独占指针,函数形参是数组的长度;若创建指向普通对象的独占指针,函数形参是要传递给对象的构造函数的。依据源码如下:

在这里插入图片描述

该图中出现了 extent_V 模板的使用,其源码如下:

在这里插入图片描述

比较难以理解,给出几个测试结果如下:、

在这里插入图片描述

(5 探讨五) 本条探讨共享指针 shared_ptr 的内存模型。读代码,主要要先掌握弄清楚一个类的数据成员。这些指针中最难的当属共享指针。根据源码得出的结论如下(也附带给出弱指针 weak_ptr 的内存模型):

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8080e8c530a04690ad52d9f3ea4414e1.png

(6 探讨六)已知一个裸指针指向堆区的一个对象。共享指针可以根据裸指针构造 shared_ptr ,即存在这样的构造函数:

在这里插入图片描述

但不允许用裸指针构造弱指针 weak_ptr ,对弱指针不存在上面的类似的构造函数;但可以根据共享指针来构造弱指针,即存在:

在这里插入图片描述

而且根据源码得知:即使仅有一个共享指针指向堆区对象,该对象上的弱引用数量也初始化为一;若再根据共享指针构造一个弱指针,则该对象上的弱引用数量就为 2 。这没有为什么,源码就是这么写的。以 1 为弱引用的计数起点,肯定有其自圆其说的地方。
补充:强引用计数是为了管理智能指针指向的对象 ,弱引用计数是为了管理也在堆区中分配的 _Ref_count_base 的子类对象
测试如下:

在这里插入图片描述

对断点调试,当仅创建一个共享指针时:

在这里插入图片描述

当继续 F10 创建一个弱引用后:

在这里插入图片描述

(7 探讨七) 允许创建空的共享指针,弱指针和独占指针,测试代码如下:

在这里插入图片描述

因为一般咱们认为这些智能是要绑定到某个对象上的。但确实智能指针不必绑定到任何对象。因为 STL库中其模板都有空的默认构造函数:

在这里插入图片描述

以及:

在这里插入图片描述

以及:

在这里插入图片描述
以及具有 nullptr 默认值的父类:

在这里插入图片描述

(8 探讨八) 王建伟老师的课本里教的 用 make_shared 创建智能指针的效率更高。因为根据裸指针创建共享指针时候,是分两次分配内存,一次创建堆区待指向的对象,再次在堆区申请内存以创建引用控制块。而用 make_shared 函数,只申请一次堆区内存,创建了包含对象和其控制块的更大的对象。相应也减少了调用对象的构造和析构函数的次数,所以效率更高。是这样的。源码轮廓如下:

在这里插入图片描述

(9 探讨九) 依据弱指针创建共享指针是可以的。源代码里有这样的构造函数,其也会检查弱指针指向的对象是否还存在,否则再创建共享指针是违法的。代码依据如下:

在这里插入图片描述

再给出其调用链:

在这里插入图片描述

以及:

在这里插入图片描述
当然也可以用弱指针的成员函数 lock 创建共享指针,函数体的代码是一样的:

在这里插入图片描述

(10 探讨十) 重新思考下继承了 enable_shared_from_this 的类。咱们知道,根据指向对象 A 的裸指针连续两次构造共享指针,就出错了。若 A 继承了 enable_shared_from_this ,则可以调用 enable_shared_from_this 的 的成员函数来创建共享指针,实现了根据裸指针创建共享指针的那么个意思。核心就是因为 enable_shared_from_this 中 有一个数据成员 weak_ptr ,此弱指针包含了对象 A 的控制块信息。从而保证系统中创建的所有共享指针,共用唯一的引用控制块。从而保证对对象 A 的正确管理与析构。
先大概看一下 enable_shared_from_this 的构造与析构, copy 构造与赋值运算符的语义,其与共享指针、对象 A 的析构息息相关:

在这里插入图片描述
以下列出参考代码,待会分析相关对象的创建与析构:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接着依据上面的构造与析构函数举例分析:

在这里插入图片描述

另外补充下上面相关基类的析构函数,大部分都为空的其实。

在这里插入图片描述

(11 探讨十一) 独占指针的 get() 与 release( ) 函数的区别:

在这里插入图片描述

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值