在C++中,分配内存的操作一般如下:
class FOO{...};
FOO *fp = new FOO;
.........
delete fp
在new 操作中可以分为两步:
而在delete操作中也可以分为两步:
STL 的 allocator 将几个操作都区分开来,内存申请由 alloc::allocatate() 负责,内存释放由alloc::deallocate()负责。对象的构造由::construct()负责,析构由::destory()负责。
STL中负责对象构造和析构的全局函数定义在了
// 开放接口
template
inline void construct(_T1* __p, const _T2& __value) {
_Construct(__p, __value);
}
// 开放接口
template
inline void construct(_T1* __p) {
_Construct(__p);
}
template
inline void _Construct(_T1* __p, const _T2& __value) {
new ((void*) __p) _T1(__value);
}
template
inline void _Construct(_T1* __p) {
new ((void*) __p) _T1();
}
construct 接口没啥特别的操作,只是将根据传入的参数来选择调用的构造方式。
template
inline void destroy(_Tp* __pointer) {
_Destroy(__pointer);
}
template
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
_Destroy(__first, __last);
}
desotry 则分为两种,一种是传入单个对象的指针,另一种则传入一组迭代器。
template
inline void destroy(_Tp* __pointer) {
_Destroy(__pointer);
}
template
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
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
_Destroy(__first, __last);
}
template
inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) {
// __VALUE_TYPE 取得迭代器所指对象类型
__destroy(__first, __last, __VALUE_TYPE(__first));
}
template
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
void
__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
for ( ; __first != __last; ++__first)
destroy(&*__first);
}
template
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}
迭代器版本则会取得迭代器所指的对象类型来判断对象的析构函数是否是traivial 的。 (_Trivial_destructor中是如何做到判断的,书上要在第三章才能知道,这边也还没学习到
STL对于对象的构造和析构调用图如下:
