STL源码剖析:【2】空间配置器-stl_construct.h
SGI特殊空间配置器:std::alloc
new 运算符含有两个阶段的过程:(1):申请内存(内存分配) (2)调用构造函数初始化 同理delete也有两个过程。
为了精密分工STL allocator决定将两个阶段操作区分开来: 内存配置与释放alloc::allocate()与alloc::deallocate()完成
对象构造过程由::construct 和::deconstruct(destroy)完成 分别对应<memory>下的<stl_alloc.h>和<stl_construct.h>
memory : 分为
1.<stl_construct.h> 包含全局函数:construct/destroy
2.<stl_alloc.h> 包含一二级配置器 ,命名为 alloc
3.<stl_uninitialized.h> 包含几个全局函数用来填充Fill和复制Copy大块内存数据 :
- un_initialized_copy
- un_initialized_fill
- un_initialized_fill_n
Construct:
首先讲一下stl_construct.h中的construct与destroy函数。
template<class T1,class T2>
inline void construct(T1 *p,const T2 &value){
new (p) T1(value); // placement new 定向 new , p为Raw(原生)内存地址,value为存储内容
//new 操作上面讲过,已经分为了明显的两个过程,内存分配以及初始化,现在则是对内存分配之后的内存
//的初始化操作 , 即对特定内存地址进行对象初始化 }
template<class T1,class T2> // destroy第一个版本
inline void destroy (T1 *p) { p->~p();} //调用对象析构函数
template<class ForwardIterator> // destroy第二个版本(为迭代器iterator提供接口)
inline void destroy (ForwardIterator first,ForwardIterator last) {
_destroy(first,last,value_type(value));} //调用对象析构函数
template<class ForwardIterator> // 第二个版本内部调用
inline void _destroy(ForwardIterator first,ForwardIterator last) {
typedef typename _type_traits<T>::has_trivial_destruct trivial_destruct
_destroy_aux(first,last,value_type(value),trivial_destruct());
} //调用对象析构函数
template<class ForwardIterator> // has trivial destruct is false
inline void _destroy_aux(ForwardIterator first,ForwardIterator last, _false_type) {
for( ; first<last ; first++)
destroy(&*first);} //调用对象析构函数
template<class ForwardIterator> // has trivial destruct is true
inline void _destroy_aux(ForwardIterator first,ForwardIterator last, _true_type) {} //空函数
图片来源:STL源码剖析p52
文中特别指出,has_trivial_destructor 的介入使得调用迭代器对一块内存进行destruct的时候,会提高效率(因为调用没有必要的destruct是对性能的降低),其中trivial指代无意义的,无用的 ,与之相反的是no-trivial 有用的。
在深入理解C++对象模型一书中说明:C++中,编译器并不会对所有的Class都会提供一个默认的construct/deconstruct函数,只在以下5中有必要情况中出现:
- 内聚对象即class object memeber 中提供显示的默认构造函数
- 基类中提供显示的默认构造函数
- 含有virtual修饰的函数
- 基类中含有virtual修饰的函数
- 虚继承某一Class
使用has_trivial_destructor ,对不具有或者trivial的destruct的屏蔽,在first与last之间有很多的对象的时候是性能提升的