stl list(gcc 4.8.5)

首先,在使用STL中的list数据结构的时候,会使用#include <list>进行相应头文件的引入,而后创建list对象,使用remove等成员函数,如果你突发奇想,抱着既然template模板函数必须在构建的时候对使用位置可见,不能模板类函数定义在一个单独的目标文件中这种想法,去点开他的声明位置,想看看具体实现,你就会惊奇的发现,里面只有一个声明,没有任何定义,如果这个时候留意一下打开的头文件,会发现他打开的并不是list文件,而是stl_list.h文件,如果你点开引用的list文件,会发现该文件中引用了stl_list.h文件,另外还include了另外一个tcc文件,list.tcc文件。而上述的没有找到的一些成员函数定义就在此处;即在查看源代码的时候,会经常有这种情况,就是有些头文件是组合式的,单个拆开不能使用,只有按照头文件顺序引用,才可以正常使用这些头文件;

言归正传,对于一个list来说,或者说对于任何一个容器,首先需要了解的就是空间分配机制;在此基础上,进行讨论,对于一个链表来说,本质上就是一个个节点通过prev和next指针指向前一个或后一个节点,这样整个的数据结构构成了链表;

那么就实现而言,该版本中对链表头和链表体进行了拆分,即将用于链接各个链表节点的prev和next指针组成结构_List_node_base,而带有数据体的结构为_List_node,也就是结构的拆分收发,这样在没有链表节点的时候,只需要维护一个_List_node_base数据即可,节省一定空间;而初始化的时候就是将prev和next都指向本身,这里的意义应该是为了兼容STL对数据范围的定义为[begin, end),如果设置为NULL,那么就没有begin和end了;

对于一个节点,这里将prev和next组成的_List_node_base称为节点头,用于节点之间的连接,_List_node除了节点后之外的内容为节点体,就是节点承载的信息;两个合起来就是一个节点;这里有个有意思的地方就是节点体在节点头之后,一次对于一个节点直接使用节点头指针即可引用该节点的节点头;

那么对于一个节点创建:首先就是创建一个节点,实现就是基于容器分配类申请一片空间,然后使用传入参数对其进行构造,这样就完成了一个节点的创建,创建完毕之后就是节点之间的连接,连接就是插入在传入的链表节点位置,就是插入在原本位置的节点B原本位置之前的位置之间;

修改的话直接使用迭代器找到对应位置进行修改即可,另外迭代器的操作符都是重载过的,本质上就是基于节点头进行节点的前后移动;

对于一个节点的删除:整体操作和创建过程相反,首先就是将节点从链表中移除,移除完毕使用容器存储类型的析构函数对其进行析构,然后释放删除对应的节点空间。

posted @ 2021-06-07 09:22  呵哈呵  阅读(27)  评论(0)    收藏  举报