空间配置器(allocator)这个概念在阅读源码之前我根本没有听过,原以为内存分配都是使用new和delete运算符(注意和operator new、placement new、operator delete以及placement delete不同)。在实际使用STL编程时也很少会遇到自己去实现一个空间配置器的情况。事实上,STL容器背后都要依靠空间配置器去分配空间。在阅读容器等STL组件的实现之前如果不了解空间配置器的原理,就会造成阅读上的困难。在侯捷的《STL源码剖析》一书中说道:为什么不说allocator是内存配置器而说它是空间配置器呢?因为空间不一定是内存,空间也可以是磁盘或其他辅助介质。但是目前我还没遇到过除内存外的资源配置情况,下文介绍SGI STL中的源码也都是对内存的配置。
根据STL的规范,allocator必须实现以下接口:
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
定义了用于iterator traits的相关型别,具体到iterator traits技术再介绍。
allocator::rebind
一个类模板,内部声明了类型other,代表allocator<U>。如果有了allocator<T>,想要allocator<U>和allocator<T>有相同分配策略,那么allocator<U>等同于allocator<T>::rebind<U>::other。
allocator::allocator() allocator::allocator(const allocator&) template<class U> allocator::allocator(const allocator<U>&) allocator::~allocator()
alllocator的默认构造函数、复制构造函数、带模板的复制构造函数,以及析构函数。
pointer allocator::address(reference x) const //等同于&x pointer allocator::address(const_reference x) const //等同于&x
返回对象地址,区别在于传入参数是否是const
void allocator::allocate(size_type n, const void* = 0)
分配空间但不初始化
void allocator::deallocate(pointer p, size_type n)
回收空间
void allocator::max_size() const
返回可成功配置的最大量
void allocator::construct(pointer p, const T& x)
等同于 new ((void *) p) T(x)
void allocator::destroy(pointer p)
等同于 p->~T()
SGI实际使用的配置器为alloc而不是allocator,且不接受任何参数。如果要在程序中使用SGI提供的配置器不能写成类似于
vector<int, std::allocator<int> > iv
而是
vector<int, std::alloc> iv;
说明:在Visual Studio 2017中上面的定义没有什么问题,gcc/g++没有测试过不知道可不可以。第二个vc++肯定不行,g++未知。
SGI STL为每个容器都指定了缺省的空间配置器为alloc,如下面vector的声明:
template<class T, class Alloc = alloc> class vector { ... };