STL源码剖析之allocator(2)

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来决定是否要调用析构操作。

posted @ 2018-01-30 19:56  dreamnwx1  阅读(144)  评论(0编辑  收藏  举报