C++ STL标准库与泛型编程(二)分配器、List、Iterator

一、分配器 allocators

先谈谈 operator new() 和 malloc()

所有C++平台上的分配动作,最后都会调用 malloc(),销毁都会用 free(),然后根据在不同的系统(win linux unix)下去调用不同的 API 实现内存的索取。

malloc()实际分配的空间内存大小会比要求的大,会加上 cookies (记录了本次申请的模块大小) 等 额外开销,并考虑 alignment 内存对齐(详细的分配细节会在内存管理中详述)。

分配器源码

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第1张图片

 allocator 只是以 ::operator new() 申请内存,每次申请的内存很小时,额外开销( malloc 造成 )占用的比例就很大

上例中 allocator() 类名后面直接加一个空的圆括号,会形成一个没有名称的临时对象

VC 与 GCC 4.9 编译器中:

  1. allocator 的操作都是通过调用 C 中的 malloc() 和 free() 来实现的,因此会带来大量的额外开销。
  2. allocator 的接口调用类方法会遇到很多问题,free 时不知道内存大小,但是通过对象调用的方案则不会遇到问题。

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第2张图片

GCC 2.9 编译器中 — 使用独有的分配器 alloc:

通过一个链表组 free list,表示其下挂的不同大小的内存元素(8,16,24......),只有每个链表组下申请的一大块内存会有 cookies 冗余,其内部的内存被分为相等的小块存储内容,以指针连接起来,小块就不再有冗余的问题。

GCC 4.9 中的 __pool_alloc 就是2.9中的 alloc。使用例:vector> vec;

容器之间的关系

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第3张图片

 早期的STL容器之中有只有“包含”关系,没有继承。


二、List 链表

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第4张图片

  1. List 本身只包含一个 _list_node* 4字节的指针。
  2. List 中只是 typedef 了 iterator 的类型,使用时要单独声明,例:list::iterator ite;
  3. List 的尾节点为空,由 iterator.end() 指出。所有的容器的 iterator 都会设计成一个 class 以满足 ++ 指向下一个元素等智能类指针操作。

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第5张图片

iterator 的类定义,一般包含:

  1. 一些必要的 typedef — 必须的五种相关类型
  2. operator 重载

操作符重载仿照整数运算的形式,因为整数运算不能有 (i++)++,所以迭代器的 前++ 函数 返回类型为 引用,后++ 函数 返回类型为 类型。

重载 operator * 与 -> 时,* 为取值操作,返回引用,->可能会做赋值,返回为 指针。

G4.9 相较于 G2.9 的改进:

  1. iterator 的模板参数只有一个,易于理解
  2. node 结构有其 parent _List_node_base
  3. node 的成员 向前向后的指针 的 type 比较精确
  4. node 的成员是两个 pointer _M_next 和 prev,组成的节点作为尾节点代替 2.9 中的空尾节点

三、Iterator 所需要遵循的原则

算法通过迭代器去操作容器,迭代器必须回答算法的五个问题

  • Associated types

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第6张图片

  1. iterator_category 迭代器类型 — 输入、输出、正向、双向、随机访问 以便采取最佳的操作方式
  2. value_type — 迭代器所指的元素的数据类型
  3. difference_type — 两个迭代器之间的距离应该用什么类型表现

后两种从来未被用到。     

提出问题:如果算法使用 简单指针 作为一个迭代器呢?如何回答算法所要求的这些信息?

 

  • Traits (特征、特性) — 人为设计的 特征提取器

C++ STL标准库与泛型编程(二)分配器、List、Iterator_第7张图片

算法询问 iterator_traits, iterator_traits去询问迭代器或者简单指针(利用了偏特化

 

你可能感兴趣的:(STL,Cpp,STL,模板)