STL源码阅读笔记-对象的构造与析构

STL 中对象的构造和析构

在C++中,分配内存的操作一般如下:

class FOO{...};
FOO *fp = new FOO;
.........
delete fp

在new 操作中可以分为两步:

  1. ::operator new 申请内存
  2. 在申请的内存上调用FOO的构造函数构造对象

而在delete操作中也可以分为两步:

  1. 调用FOO的析构函数
  2. ::operator delete 释放内存

STL 的 allocator 将几个操作都区分开来,内存申请由 alloc::allocatate() 负责,内存释放由alloc::deallocate()负责。对象的构造由::construct()负责,析构由::destory()负责。

STL中负责对象构造和析构的全局函数定义在了 <stl_construct.h> 中,内容不多,才100行左右的代码

construct()

// 开放接口
template <class _T1, class _T2>
inline void construct(_T1* __p, const _T2& __value) {
  _Construct(__p, __value);
}

// 开放接口
template <class _T1>
inline void construct(_T1* __p) {
  _Construct(__p);
}

template <class _T1, class _T2>
inline void _Construct(_T1* __p, const _T2& __value) {
  new ((void*) __p) _T1(__value);
}

template <class _T1>
inline void _Construct(_T1* __p) {
  new ((void*) __p) _T1();
}

construct 接口没啥特别的操作,只是将根据传入的参数来选择调用的构造方式。

destory()

template <class _Tp>
inline void destroy(_Tp* __pointer) {
  _Destroy(__pointer);
}

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

desotry 则分为两种,一种是传入单个对象的指针,另一种则传入一组迭代器。

template <class _Tp>
inline void destroy(_Tp* __pointer) {
  _Destroy(__pointer);
}

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

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*) {}
#ifdef __STL_HAS_WCHAR_T
inline void _Destroy(wchar_t*, wchar_t*) {}
#endif /* __STL_HAS_WCHAR_T */

传入当个指针的版本会根据对象的具体类型来决定是否调用特化版本的析构,不存在特化的则统一调用对象的析构函数。

// 开放接口
template <class _ForwardIterator>
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
  _Destroy(__first, __last);
}


template <class _ForwardIterator>
inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) {
	// __VALUE_TYPE 取得迭代器所指对象类型
  __destroy(__first, __last, __VALUE_TYPE(__first));
}

template <class _ForwardIterator, class _Tp>
inline void 
__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*)
{
  typedef typename __type_traits<_Tp>::has_trivial_destructor
          _Trivial_destructor;
   // 这边会判断这个对象类型是否是trivial 类型
  __destroy_aux(__first, __last, _Trivial_destructor());
}


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) {}

迭代器版本则会取得迭代器所指的对象类型来判断对象的析构函数是否是traivial 的。 (_Trivial_destructor中是如何做到判断的,书上要在第三章才能知道,这边也还没学习到

小结

STL对于对象的构造和析构调用图如下:
对象的构造与析构

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值