(1)list源码分析,基于c++ 和vs2019,cpp20标准。结构确实如图,双向环形链表。
++ 经后来分析,上述的结构还可以具体些,自己画了一个:
(2) 关于list类型变量的初始化思考,如下图:
我们可以如此初始化 list 变量并赋值。但实际上 list 并没有如此直接对应的构造函数。实际编译器的做法是,把{9,10,11} 初始化给了initializer_list类型的变量。如下图:
内存中确实有这样的9,10,11 的数据序列,其起始和终止地址作为指针初始化了 initializer_list 变量。然后再以这个initializer_list 变量来作为实参,来初始化 list 变量,调用如下的 list 构造函数:
这些都是咱们猜测的编译器的编译原理。毕竟没看过c++编译器是怎么编译这些代码的。但咱们可以反汇编验证一下:
可见,代码力确实存在对 initializer_list 的使用。确实是这么构造 list 的。 谢谢
(3)数据结构
(4)现在学习容器的删除函数,主要是迭代器的使用:
++ 此 erase ( ) 函数的源码如下:
(5)继续学习迭代器的删除操作,目前的一个结论是,不可以对指向 list . begin()这个首元素进行递减操作:
(6)同理,迭代器的递增操作也不适用于 end()迭代器:
(7)以上讨论,确定了使用 删除 erase()函数的大体的代码框架:
++ 给出源代码版本:
#include <iostream>
#include <list>
using namespace std;
int main() // 本例中编写的 for 的循环条件,也很精妙!!
{ // 本测试的意图是删除链表里所有的 2 ,且 2 既在开头也在链尾
list<int> myList{2,1,2,2,2,3,2,4,2,5,2,2,2,6,7,8,9,2,2,2};
auto iterBegin = myList.begin(), iterEnd = myList.end();
for (auto iter = iterBegin; iter != iterEnd ; ) //省略递增条件
if (*iter == 2)
iter = myList.erase(iter);
else
iter++;
for (auto iter = myList.begin(); iter != iterEnd; iter++)
cout << *iter << " ";
cout << endl;
return 0;
}
(8)
谢谢