SGI虽然定义了名为allocator的配置器,但从未使用过。SGI的allocator只是包装了C++的::operatpor new和::operator delete,效率不高。STL中内存配置操作由alloc::allocate()负责,内存释放操作由alloc::deallocate()负责;对象构造操作由::construct()负责,对象析构操作由::destroy()负责。
STL配置器定义于头文件
#include <stl_alloc.h> //负责内存空间的配置与释放
#include <stl.construct.h> //负责对象内容的构造与析构
构造和析构:construct() 和 destroy()
construct函数内部使用placement new完成对象的构造:
template<class T1, class T2>
inline void construct(T1 *p, const T2& value)
{
new (p) T1(value);
}
destroy函数拥有多个版本实现:
template<class T>
inline void destory(T* pointer)
{
pointer->~T(); //调用析构函数
}
//接受两个迭代器,对区间的destory操作
template<class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
__destroy(first, last, value_type(first));
}
//针对不同型别调用不同的__destory_aux函数
template<class ForwardIterator, class T>
inline void __destory(ForwardIterator first, ForwardIterator last, T*)
{
typedef typename __type_traits<T>::has_trival_destructor trival_destructor;
__destroy_aux(first, last, trival_destructor());
}
//拥有non-trival destructor的版本
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type)
{
for(; first < last; ++first)
destroy(&*first); //对区间每一个对象执行析构
}
//拥有trival destructor的版本
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __true_type)
{
//什么都不做
}
//以下是destroy()针对迭代器为char* 和w_char*的特化版
inline void destroy(char*, char*) {}
inline void destroy(w_char*, w_char*) {}
总结上面的代码,construct函数接受一个指针p和一个初值value,其用途是将初值写到指针开始的位置上,这个操作可以通过C++的placement new完成。destroy函数拥有两个版本:一个对指针指向对象做析构;另一个对区间做操作:如果区间元素有non-trival的析构函数,那么对区间每一个元素执行析构操作,否则什么都不做。destory函数的第二个版本通过value_type宏获取迭代器所指对象的型别,传递给__destory函数;在_destory函数内部通过__value_traits来确定该型别的析构函数是否是trival,通过重载函数_destory_aux来决定是否要调用析构操作。