分配器往往会让人感到畏惧,甚至包括一些专家在内。但不必害怕,因为你已经掌握了相当的内存管理知识和技能(而且鉴于你在阅读本书,很可能对这个话题也充满好奇)。既然如此,在我们真正定义分配器之前,首先要回答的问题是:“为什么分配器存在?” 为什么要在内存管理代码中引入这样一层,从而增加复杂性?
好吧,这是因为这是 C++,而 C++ 的核心理念就是赋予用户控制权,我们的解释也应从这里开始。打个比方,可以回想一下迭代器(iterators):它们为何有用?又是如何改善你作为开发者的生活的?将“如何遍历序列中的元素”与“元素在序列中如何组织”解耦开来,这样就可以写出一段代码,计算 std::list<int> 或 std::vector<short> 中所有值的总和,而无需关心在第一种情况下是在通过指针链接的节点中导航,还是在第二种情况下遍历连续内存中存储的对象。
迭代器的美妙之处就在于这种“遍历逻辑”与“数据组织”的解耦。同样地,分配器(allocators)所做的,就是将“数据组织”与“底层存储的获取或释放方式”解耦开来。这可以独立于内存管理机制来理解和设计容器的特性,从而使得容器在更多场景中变得有用,远超其原本的适用范围。
对于容器而言,分配器(至少是即将讨论的“传统”模型中的分配器)是对硬件的一层非常薄(非常非常薄)的抽象。对于容器来说,分配器所表达的是诸如“什么是地址?”、“如何将一个对象放置到某个位置?”、“如何在某个位置销毁一个对象?”等问题的答案。从某种意义上讲,对容器而言,分配器本质上就代表的是硬件。