侯捷STL 13. 深度探索list

1. list

  • list 在 G2.9 中用的分配器是 alloc
  • list 中的 data 是 node,类型是 link_type,link_type 是 list_node* ,是一个指针指向 list_node,指针的大小为 4 个字节(32位)
  • __list_node 中有三个变量,分别是 data,prev,next,prev,next是指针,类型是 void_pointer ,即 void用 void* 后还要转型,在后续的 G4.9 中有优化
  • list 去申请内存,要有三部分,两个指针,一个 data
  • 因为 list 是非连续空间,所以 iterator 不能是指针,由于链表是非连续的 iterator++,不能偏移到下一个 node
  • 所有的容器要用 iterator,都要有一个typedef,iterator 代表某一个 class
  • list_itertor 是一个 smart_pointer,是一个 class
  • list的底层是双向环状链表,是前闭后开区间,有一个虚拟的节点,表现在图中就是灰色的那部分,也是 end() 所指向的部分,因为要实现前闭后开,所以就要构建出一个不属于本容器的节点,这样end(),才是最后一个节点的下一个节点

2. list_iterator

  • iterator 中会有大量的操作符重载,因为要模拟指针,比如 *(解引用)、->、++
  • 所有容器的 iterator 都至少有以上五个typedef

3. ++操作符重载

  1. operator++() 是前加加,operator++(int) 是后加加
  2. operator++() 的实现是 取 node 的 next ,将其赋值给自己本身,实现向后偏移到下一个节点
  • 同理,operator--() 是取出 node 的 prev 指针,赋值给本身
  1. operator++(int) 的实现中
  • 第一段代码,self tmp = *this
  • *this 的 * 并不是调用的 operator*() 而是 调用拷贝构造函数,因为 *this 已经被解释为拷贝构造的参数
  • 第二段代码,++*this
  • 不会调用 operator*(),因为 *this 已经作为 operator++() 的参数
  1. 在 C++ 中,由于整数不能做两次连续的后加加,但是可以连续的两次前加加,所以iterator在设计前加加的时候,返回的就是引用,而后加加返回的则不是引用,这样做是为了模拟整数的++运算符

4. *与-> 操作符重载

  1. operator*() 返回的是 node 的 data,这个data可以是一个对象
  2. operator->() 返回的是 (*node).data 的地址,假设 node 的 data 是一个对象,那么取出来以后对这个对象取地址,就可以使用 -> 操作符,对其进行操作,可以看成是对象的一个指针,这样就可以修改其中的 public 的值,或者调用其中的 public 的函数
  • 根据上图,iterator 不是一个指针,所以利用->操作符,会先调用它的 operator()->重载函数,直到取到一个地址,也就是一个指针,指向要操作的数,这是才可以进行成员的存取

5. G4.9 改进

  • 原本传入 list_iterator 的参数要三个,分别是 T,T&,T*,现在只需要传入一个了
  • 只需传入一个以后,typedef 也进行了修改,改成了 typedef _Tp* pointer,typedef _Tp& reference,在typedef定义的时候才加上操作符,变成指针或者引用
  • 指针部分也改了,现在 list node分成了两部分,一部分是_list_node,继承了 _list_node_base,其中_list_node_base 中含有前后两个指针,他们的类型也从原来的 void* 改为了 结构体本身的指针类型

6. G4.9 变化

  • 在4.9中,list 变为 8 个字节

  • list本身没有大小,所以大小为0,要看他的父类
  • 父类中有一个data
  • 父类内含的 List_impl 内含 List_node_base,其中有两个指针,一个是 m_next,另一个是m_prev
  • 所以两个指针是 8 个字节
  • 和之前一样,list 的 node 指的就是空白节点,所以取 begin() 的时候,取的就是 node 的 next,而取end(),就是取空白节点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值