任意满足分配器使用需求的C++类都可作分配器使用。具体来说,当一个类(在此设为类A)有为一个特定类型(在此设为类型T)的对象分配内存的能力时,该类就必须提供以下类型:A::pointer(指针),A::const_pointer(常量指针), A::reference(引用),A::const_reference(常量引用)及A::value_type(值类型),如此才能以通用的方式声明对象与对该类对象的引用T。allocator提供这些指针或引用的类型定义的初衷,是隐蔽指针或引用的物理实现细节;因为在16位编程时代,远指针(far pointer)是与普通指针非常不同的,allocator可以定义一些结构来表示这些指针或引用,而容器类用户不需要了解其是如何实现的。同时类A还需提供类型A::size_type(表示所用内存大小的类型)与A::difference_type(指针差值的类型),其中size_type类型是用于表示类A所定义的分配模型中的单个对象最大尺寸的无符号整型,而difference_type类型是带符号整型,用于表示分配模型内的两个指针的差异值。
虽然按照标准,在库的实现过程中允许假定分配器(类)A的A::pointer(指针)与A::const_pointer(常量指针)即是对T*与T const*的简单的类型定义,但一般更鼓励支持通用分配器。
另外,设有对于为某一对象类型T所设定的分配器A,则A必须包含四项成员函数,分别为分配函数、解除分配函数、最大个数函数和地址函数。
分配函数用以进行内存分配,形如A::pointer A::allocate(size_type n, A<void>::const_pointer hint = 0)。其中调用参数n即为需要分配的对象个数,另一调用参数hint(须为指向已为A所分配的某一对象的指针)则为可选参数,可用于在分配过程中指定新数组所在的内存地址,以提高引用局部性,但在实际的分配过程中程序也可以根据情况自动忽略掉该参数。该函数调用时会返回指向分配所得的新数组的第一个元素的指针,而这一数组的大小足以容纳n个T类元素。在此需要注意的是,调用时只为此数组分配了内存,而并未实际构造对象。
解除分配函数形如void A::deallocate(A::pointer p, A::size_type n)。其中p为需要解除分配的对象指针(以A::allocate函数所返回的指针做参数),n为对象个数,而调用该函数时即是将以p起始的n个元素解除分配,但同时并不会析构之。C++标准明确要求在调用deallocate之前,该地址空间上的对象已经被析构。
最大个数函数形如A::max_size(),调用时返回调用一次分配函数A::allocate所能成功分配的元素的最大个数,其返回值等价于A::size_type(-1) / sizeof(T)的结果 。
地址函数形如A::pointer A::address ( reference x ),调用时返回一个指向x的指针。
除此以外,由于对象的构造/析构过程与分配/解除分配过程分别进行 ,因而分配器还需要成员函数A::construct(构造函数)与A::destroy(析构函数)以对对象进行构造与析构,且两者应等价于如下函数:
template <typename T>void A::construct(A::pointer p, A::const_reference t) { new ((void*) p) T(t); } template <typename T>void A::destroy(A::pointer p){ ((T*)p)->~T(); }
以上代码中使用了placement new语法,且直接调用了析构函数。
分配器应是可复制构造的,任举一例,为T类对象而设的分配器可由另一为U类所设的分配器构造。若某分配器分配了一段存储空间,则这段存储空间只能由与该分配器等价的分配器解除分配。分配器还需要提供一个模板类成员函数template <typename U> struct A::rebind { typedef A<U> other; };,以模板 (C++)参数化的方式,借之来针对不同的数据类型获取不同的分配器。例如,若给定某一为整型(int)而设的分配器IntAllocator,则可执行IntAllocator::rebind<long>::other以获取对应长整型(long)的相关分配器。实际上,stl::list<int>实际要分配的是包含了双向链表指针的node<int>,而不是实际分配int类型,这是引入了rebind的初衷。
与分配器相关联的operator ==,仅当一个allocator分配的内存可以被另一个allocator释放时,上述相等比较算符返回真。operator !=的返回结果与之相反。