STL空间配置器(一)

这里主要说的是具备次配置力的SGI空间配置器。

SGI STL的配置器与众不同,也与标准规范不同,其名称是alloc而不是allocator,而且不接受任何参数。

比如:

Vector<int,std::allocator<int>>  iv; //此写法错误

Vector<int,std::alloc>  iv;//此写法正确

注意:

SGI STL的每一个容器都已经指定其缺省的空间配置器为alloc

SGI STL也定义了一个符合部分标准,名为allocator的配置器,但是SGI从未使用过它,也不建议我们使用,主要是因为效率不佳,他只把C++::operator new::operator delete做一层薄薄的包装而已。

 

下面我们要说的是SGI的特殊的空间配置器。

 

SGI特殊的空间配置器----->std::alloc

我们所习惯的C++内存配置和内存释放的操作是:

先配置内存,再构造对象。

先对象析构,再释放内存。

 

在这里,为了精密分工,所以决定将这个两个阶段操作区分开来处理。

内存配置操作由alloc::allocator()负责,内存释放操作由alloc::deallocator()负责。

对象构造操作由::construct()负责,对象析构操作由::destroy()负责。

(就是将内存配置,释放和对象构造,析构分开来进行)

 

配置器定义于<memory>之中,而SGI<memory>内包含以下两个文件:

#include  <stl_alloc.h>          //负责内存空间的配置与释放

#include  <stl_construct.h>      //负责对象内容的构造与析构


如下图:


1.下面一起来看一下构造和析构基本工具:construct() destroy()

以下是<stl_construct.h>的部分内容:

#include <new.h>

template <class T1,class T2>
inline void construct(T1 * P,const T2& value)
{
	new(p) T1(value); //placement new 的调用
}
/*
Placement new它用于在给定的内存中初始化对象(注意:此处是已经给定的内存)
Placement new的调用方式是:new(p)  T1(value);  //(其中p是已经申请好的内存)
*/

//以下是destroy()第一版本,接受一个指针
template <class T>
inline void destroy(T* pointer)
{
	poniter-> ~T();    //调用dtor ~T()
}

//以下是destroy()第二版本,接受两个迭代器,此函数设法找出元素的数值型别
//进而利用_type_traits<>求取最适当的措施
template <class ForwardIterator>
inline void destroy(ForwardIterator first,ForwardIterator last)
{
	_destroy(first,last,value_type(first));
}

//判断元素的数值型别(value type)是否有trivial destructor
template <class ForwardIterator,class T>
inline void _destroy(ForwardIterator first,ForwardIterator last,T*)
{
	typedef  typename _type_traits<T>::has_trivial_destructor  trivial_destructor;
	_destroy_aux(first,last,trivial_destructor());
}

//如果元素的数值型别(value type)有non_trivial destructor:
template <class ForwardIterator>
inline void _destroy_aux(ForwardIterator first,ForwardIterator last,_false+type)
{
	for(;first<last;++first)
	{
		destroy(&*first);
	}
}

//如果元素的数值型别(value type)有trivial destructor:
template <class ForwardIterator>
inline void _destroy_aux(ForwardIterator,ForwardIterator,_true_type)
{}

//以下是destroy()第二版本针对迭代器为char *和wchar_t*的特化版
inline void destroy(char *,char *){}
inline void destroy(wchar_t*,wchar_t*){}

由以上代码我们可以知道:

(1)construct()函数接受一个指针p和一个初值value,该函数的用途就是将初值设定到指针所指的空间上。(所以此处用的是C++中的placement new)

(2)Destroy()函数有两个版本

     a)第一个版本接受一个指针,准备将该指针所指的对象析构掉(此处直接调用析构函数即可)

     b)第二个版本是接受两个迭代器firstlast,准备将[firstlast)范围内的所有对象析构掉,我们不知道这个范围有多大,万一很大,而每个对象的析构函数都无关痛痒,那么一次次调用个这些无关痛痒的析构函数对效率是一种伤害。因此,这里首先利用value_type()获得迭代器所指对象的型别,再利用_type_traits<T>判断该型别的析构函数是否无关痛痒,若是(_true_type),则什么也不做就结束;若否(_false_type),这才以循环方式巡防整个范围,并在循环中每经历一个对象就调用第一版本的destroy().


注意:这两个作为构造和析构之用的函数被设计为全局函数,符合STL的规范。

STL还规定配置器必须拥有名为construct()destroy()的两个成员函数。

(然而真正在SGI STL中大显身手的std::alloc的配置器并未遵守这一规则)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值