【STL】空间配置器剖析(完结)

内存基本处理工具


STL提供了五个全局函数用于处理空间,分别为:

1. construct 用于构造;
2. destroy 用于析构;
3. uninitialized_copy(first, last, result) 将[first,last)范围内的对象复制到result处;
4. uninitiated_fill(first, last, X) 将[first,last)范围内的内存用对象X的副本填充;
5. uninitiated_fill_n(first, n, X) 将first开始的n个连续的内存空间用X的副本填充;


前面提到对于destroy的实现,如果对象的析构函数是trivial的,那么什么都不用做,同样的,对于uninitialized_copy和uninitiated_fill / uninitiated_fill_n,如果对象时POD类型,那么可以直接通过复制内存的方式来实现,对于普通的POD类型,通过上层的copy函数来实现复制填充,对于char*/wchar_t*,则提供对应的特化版本,通过memmove实现(和memcpy相比,memmove支持重叠内存操作);如果不是POD类型,那么就只能通过construct实现了。


关于POD类型:

POD类类型就是指class、struct、union,且不具有用户定义的构造函数、析构函数、拷贝算子、赋值算子;不具有继承关系,因此没有基类;不具有虚函数,所以就没有虚表;非静态数据成员没有私有或保护属性的、没有引用类型的、没有非POD类类型的(即嵌套类都必须是POD)、没有指针到成员类型的(因为这个类型内含了this指针)。

简单的说直接的内存复制操作对POD类型没有影响,比如用memset进行初始化,但这对于非POD类型是不可行的,比如存在虚函数的情况下。对于POD类型我们采用最有效率的复制手法,而对于no-POD类型的采取最安全的做法。


判断一个类型是否是POD类型,也是通过__type_traits萃取出来的。

// POD类型,通过高层的copy实现
template <class _InputIter, class _ForwardIter>
inline _ForwardIter 
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __true_type)
{
  return copy(__first, __last, __result);
}
 
// 非POD类型,通过调用_Construct进行构造对象
template <class _InputIter, class _ForwardIter>
_ForwardIter 
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __false_type)
{
  _ForwardIter __cur = __result;
  __STL_TRY {
    for ( ; __first != __last; ++__first, ++__cur)
      _Construct(&*__cur, *__first);
    return __cur;
  }
  __STL_UNWIND(_Destroy(__result, __cur));
}
 
// 中间函数,通过__type_traits<_Tp>::is_POD_type萃取出POD类型
template <class _InputIter, class _ForwardIter, class _Tp>
inline _ForwardIter
__uninitialized_copy(_InputIter __first, _InputIter __last,
                     _ForwardIter __result, _Tp*)
{
  typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;
  return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());
}
 
// 用户接口函数
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
  uninitialized_copy(_InputIter __first, _InputIter __last,
                     _ForwardIter __result)
{
  return __uninitialized_copy(__first, __last, __result,
                              __VALUE_TYPE(__result));
}
 
// char* 特化版本
inline char* uninitialized_copy(const char* __first, const char* __last,
                                char* __result) {
  memmove(__result, __first, __last - __first);
  return __result + (__last - __first);
}
 
// wchar_t* 特化版本
inline wchar_t* 
uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
                   wchar_t* __result)
{
  memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
  return __result + (__last - __first);
}

到此对于空间配置器的剖析已经完结,知识是短效记忆的,因此为了更好的理解,我们应该每次遇到问题时,都返回去复习哈,每次肯定都有不同的理解深度的,但愿每位看完这个系列的读者能从中理解STL的空间配置器,并有所启发,如对文章有什么问题或者建议的,麻烦留言,不吝赐教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值