作为最具代表性的容器,List成为最先被剖析的容器。
    image.png
    上面的一张大图,概括了G2.9版本的List容器的主干部分(这里省略掉它的一堆成员函数):
    前面三个typedef定义的变量类型:
    其中唯一的数据(占有内存的部分)在后面的 **node**里面,而node又是一个list_node类指定的指针,32位机器上一个指针占有4个字节,所以List的一个元素定义占有四个字节,关于主要的List_node定义,在右上方给出,它是由2个指针,一个T类型数据组成的结构体,这也表明了List的实际结构是由以上组成的。当然由于版本时期的局限性,这里的指针是void*显然是不够好的,所以在G4.9版本改为了该数据类型的指针。
    下面要介绍所有容器都有的重要的一部分——iterator,上图右下角是iterator的具体类内定义,在G2.9版本里面,一个迭代器要传三个参数进去,分别是数据和他的指针、引用。

    image.png
    上面是listiterator的内部类定义,而下面的这张图,是介绍其中的两个运算符重载函数,前++和后++,在实际定义中,用参数列表里面的(int)来区分,有int的是后++,当然int只是标记,没有实际类型含义。
    image.png
    有趣的是,在做一次iterator的后加加操作时,里面有两个“坑”要注意一下,**self tem = *this;**的操作,并没引起operator()的运算符重载,因为前面有一个等号,先激发了“=”的拷贝构造,直接调用了拷贝构造函数,把this一起当成参数进了拷贝构造函数,返回了复制后的本身。同理,后面的一句
    **++*this;**也自是仅调用了前++()的运算符重载,没有调得到()的运算符重载。在这里也能看出来前加加和后加加的区别,后加加返回的是储存的原值,前加加直接返回之后的*
    引用_,这里要注意的是,因为前加加返回的是引用,所以可以在实际使用上一直叠加:(实现`++++i;**`)

    下面是iterator的两个运算符重载函数,它们的返回类型一个是指针,一个是引用,需要好好理解下…………
    image.png

    针对上面提到的G2.9版本的问题,下图中的G4.9版本给出改进:
    image.png
    但是,为了追求“时代新潮”,G4.9版的List具体内容由原来的一个类分变成了N个类N个继承关系,实质虽然没什么变化,但其大小从一个指针的4字节大小变成了两个指针的8字节大小。

    下面是关于链表的环状结构:为了实现“前闭后开”的区间设计在链表的首端和尾端之间,“制造”这样一个空白节点,在Iterator的begin()和end(),分别指向了首个元素的prev和尾端元素的next,这样就实现了前闭后开的结构设计(下图是G2.9)
    image.png
    这个是G4.9版本:
    image.png
    也是同样实现了之前的环状结构。