std::list 源代码解析
首先声明,下面的讲解都是针对GCC2.9,std::alloc
通过下面的源代码大家可以看到list类的内部成员是一个node,而他的类型是linktype,前面的typedef里面有介绍是一个指针,所以,当我们创建一个对象的时候,他的大小是4,只有一个指针,而listnode是一个结构体,void *的两个指针,因为list是一个双向链表,而且还是一个环状的,所有有两个指针
iterrator:我们如何查看list里面的元素呢,我们需要使用iterator迭代器,我们说迭代器是一个指针,那他到底是什么指针,除了vector和arrar,(因为他们两个的内存空间是连续的),其他的序列式容器的迭代器都是一个类类型的,因为list的各个元素相互·1独立,他们不能通过单存的++就可以实现地址的++进而取得元素,相反,他们内部需要进行某些处理获得下一个元素的位置,所以我们看到第二张图片(*node).mext,在++的重载函数里面,他首先获得里面的next,在跳转到下一个元素返回
前置版本返回一个引用【Fraction& operator++()】,后置版本返回一个const值【const Fraction operator ++(int)】。
后置版本是利用前置版本来实现的。节约代码,控制代码有余。
前置版本的效率高,因为后置版本需要调用前置版本,所有后置版本效率比前置要低。(++i比i++效率高。)
在后置版本里,人为添加一个参数(int),主要是为了区别前置版本,这个参数不会被使用。
他们的返回值一个是&,一个是非引用,
下满举一个例子
++++i
i++++
上面两个都执行两次++,但是前置的可以,后置的就不可以,所以,为了满足上面的这种要求,前置的要求返回引用,后置的不能返回引用,就可以解决是否可以前置后置两次++的问题了
***************************G4.9***********************************************
下面就是两者的主要区别list_iterator传的参数变了,省去了没有必要的引用和指针,list_node结构变了,之前point和data封装在一起,现在单独开了,
以前l2.9,空list对象4个字节,现在8个,可以看一下上面的结构,list为空。但是继承了listbase,listbase包含了listimpl,listimpl又包含了list_node_base,里面有两个指针,所以大小为8