STL内存空间的配置/释放与对象内容的构造/析构,是分开进行的。
对象的构造、析构
对象的构造由construct函数完成,该函数内部调用定位new运算符,在指定的内存位置构造对象。如下:
![](file:///D:/%E6%88%91%E7%9A%84%E6%96%87%E6%A1%A3/My%20Knowledge/temp/720808c1-4dbb-4acc-8dcf-3c3b4d3fb8dd/128/index_files/f9f4441b-8c6e-40b6-ac78-c1ddf984f9c4.png)
template <typename T1, typename T2> inline void construct(T1 *p, const T2& value) { //定位new new (p) T1(value); }
对象的析构由destroy函数完成,该函数有两个版本:接受1个指针和接收两个迭代器的版本。接受1个指针的版本直接调用指针指向的对象的析构函数完成析构;接收两个迭代器的版本的destroy会判断迭代器指向的对象类型的析构函数是否是trivial的,若是,则什么也不做,若不是,则会遍历两个迭代器所指定的范围,逐个调用第1版本的destroy。这么做的目的主要是为了析构时的效率考虑。
下图为第1版本的destroy
//destroy()第一版本,接受一个指针 template <typename T> inline void destroy(T* point) { point->~T(); }
![](file:///D:/%E6%88%91%E7%9A%84%E6%96%87%E6%A1%A3/My%20Knowledge/temp/720808c1-4dbb-4acc-8dcf-3c3b4d3fb8dd/128/index_files/1f5cfa1e-a22f-40e8-b33f-5f8827d93d21.png)
下图为第2版本的destroy
//有trivial destructor template <typename Iterator> inline void __destroy_aux(Iterator first, Iterator last, __true_type) {} //有non-trivial destructor template <typename Iterator> inline void __destroy_aux(Iterator first, Iterator last, __false_type) { for (; first < last; first++) destroy(&*first); //调用第一版本destroy() } //判断元素的值类型是否有trivial destructor template <typename Iterator, typename T> inline void __destroy(Iterator first, Iterator last, T* ) { typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor; __destroy_aux(first, last, trivial_destructor()); } //destroy()第二版本,接受两个迭代器 template <typename Iterator> inline void destroy(Iterator first, Iterator last) { __destroy(first, last, value_type(first)); }
其中,判断迭代器所指的对象类型,是通过iterator_traits模板结构体来判断的,利用了模板的参数推断功能,从而推断出该迭代器所指的对象类型。如下图所示:
![](file:///D:/%E6%88%91%E7%9A%84%E6%96%87%E6%A1%A3/My%20Knowledge/temp/720808c1-4dbb-4acc-8dcf-3c3b4d3fb8dd/128/index_files/b3c2d248-f524-4a30-af33-f5f2df7b3a5a.png)
//返回迭代器指向的对象类型 value_type* template <typename Iterator> inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&) { return static_cast<typename iterator_traits<Iterator>::value_type*>(NULL); }
//iterator traits template <typename Iterator> struct iterator_traits { typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::value_type value_type; typedef typename Iterator::difference_type difference_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; };
![](file:///D:/%E6%88%91%E7%9A%84%E6%96%87%E6%A1%A3/My%20Knowledge/temp/720808c1-4dbb-4acc-8dcf-3c3b4d3fb8dd/128/index_files/0f75a9c9-137f-40b9-b41a-c42485d0ba6c.png)