STL 空间配置器(一)

一. 概述

        空间配置器包含对象的构造与析构,内存的管理,以及其它一些全局函数。当调用new创建一个对象时,需要进行两个阶段的操作:内存分配与对象构造。同样的,当调用delete释放对象时也要进行对象的析构与内存回收。相较于对象的构造与析构,内存的管理会麻烦一些,因此先从简单的开始讨论。

 

二.构造与析构

     在stl中对象的构造操作由::construct()负责,对象析构操作由::destory()负责。这两个函数都定义在<stl_construct.h>头文件中。

2.1对象的构造

     ::construct()函数有两个重载:

// 接收一个指向内存空间的执政__p 和 初值__value作为参数
template<class _T1, class _T2>
inline void construct(_T1* __p, const _T2& __value)
{
    new (__p) _T1(__value);
}

// 只接收一个指向内存空间的执政__p
template<class _T1>
inline void construct(_T1* __p)
{
    new (__P) _T1();
}

       其中的new操作与平时使用的方式不同,“new(指针) 类型(值)” 这种用法是在一个已经分配了空间的地址上重新构造对象。例如:  int a = 3;   int *p = &a;  new((void*)p) int(5);  cout << *p;此时的输出结果就是5。当然这块地址空间应该是未初始化过的或是只存有POD类型的数据,否则会造成构造函数与析构函数调用次数的不匹配,从而导致一些错误。

2.2 对象的析构

       ::destory()函数也有两种重载,一种接收一个指针,析构该指针所指之物。第二个版本接收两个迭代器,将[first, last)范围内的所有对象析构掉。

       对于第一种,没有好解释的,直接调用析构函数,代码如下:

template <class _Tp>
inline void distory(_Tp* __pointer) {
    __pointer->~Tp();
}

       对于第二种,由于不知道迭代器的范围,万一很大,而对象为基本类型,那么会损失效率。为了避免这种情况,slt中采用了两种技术来避免:对模板函数的特化与萃取机的使用。

template <class _ForwardIterator>
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
  __destroy(__first, __last, __VALUE_TYPE(__first));
}

       先说模板函数的特化:

      stl中为用基础类型指针做为迭代器的调用,利用模板函数的特化进行了第一次区分:

inline void destroy(char*, char*) {}
inline void destroy(int*, int*) {}
inline void destroy(long*, long*) {}
inline void destroy(float*, float*) {}
inline void destroy(double*, double*) {}

     这样以基础类型指针为参数的调用便不会调用析构函数。

     接下来,stl为了区别出普通迭代器所指数据是否需要进行析构操作,而使用了两次萃取操作,第一次使用__VALUE_TYPE萃取出迭代器所指数据的类型,以该类型的对象为参数调用__destory()函数

template <class _ForwardIterator, class _Tp>
inline void 
__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*)
{
  typedef typename __type_traits<_Tp>::has_trivial_destructor
          _Trivial_destructor; // 萃取机制
  __destroy_aux(__first, __last, _Trivial_destructor());
}

    若类型Tp有非默认的析构函数则_Trivial_destructor的类型为struct __false_type,否则为 struct __true_type,以该类型的对象为参数调用重载函数__destory_aux()

template <class _ForwardIterator>
void
__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
  for ( ; __first != __last; ++__first)
    destroy(&*__first);
}

template <class _ForwardIterator> 
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}

关于stl萃取机的实现在其它博文中说明。

三.内存的分配与释放

 见博文《STL 空间分配器(二)》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值