本文最后更新于:2020年7月2日 晚上
* 之前只知道理论。。。今天就来深入剖析一下源代码。。。→_→ *
了解POD数据类型请戳传送门——什么是POD数据类型?
直接从vector的push_back进。。。
//stl\Stl_vector.h
//尾插
void push_back(const _Tp& __x) {
//先检查是否还有备用空间
if (_M_finish != _M_end_of_storage) {
//如果有,就直接在备用空间上构造元素
//construct定义在下面
construct(_M_finish, __x);
++_M_finish; //调整水位高高度
}
else
//此时已没有备用空间
//_M_insert_aux定义在下面
_M_insert_aux(end(), __x);
}
//stl\Stl_vector.h
template <class _Tp, class _Alloc>
void
vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
{
//如果此时还有备用空间
if (_M_finish != _M_end_of_storage) {
//在备用空间起始处构造一个元素,并以vector最后一个元素值为初始值
construct(_M_finish, *(_M_finish - 1));
++_M_finish; //调整水位
_Tp __x_copy = __x;
copy_backward(__position, _M_finish - 2, _M_finish - 1);
*__position = __x_copy;
}
else { //此时没有备用空间
//计算原vector的大小
const size_type __old_size = size();
//如果原大小为0,则配置1个元素
//如果原大小不为0,则配置原大小的2倍
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
iterator __new_start = _M_allocate(__len);
iterator __new_finish = __new_start;
__STL_TRY {
//将原vector的内容拷贝到新vector
//uninitialized_copy定义在下面
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
//为新元素设定初始值为x
construct(__new_finish, __x);
//调整水位
++__new_finish;
//将原vector的备用空间中的内容也拷贝到新vector中
__new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start,__len)));
//析构并释放原vector
//destroy定义在下面
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
//调整迭代器,指向新vector
_M_start = __new_start;
_M_finish = __new_finish;
_M_end_of_storage = __new_start + __len;
}
}
//stl\Stl_uninitialized.h
//如果推导出的是POD类型,就采用针对POD最有效率的复制方法,即执行以下函数
//__true_type是由函数模板参数的推导机制得到的
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
_ForwardIter __result,
__true_type)
{
//调用STL的copy()算法,其底层使用memmove()函数,直接按照内存字节进行复制
return copy(__first, __last, __result);
}
//如果是non-POD类型,即执行以下函数
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)
//一个一个的进行元素构造,而不是像POD一样,直接进行内存字节的复制
//_Construct定义在下面
_Construct(&*__cur, *__first);
return __cur;
}
__STL_UNWIND(_Destroy(__result, __cur));
}
template <class _InputIter, class _ForwardIter, class _Tp>
inline _ForwardIter
__uninitialized_copy(_InputIter __first, _InputIter __last,
_ForwardIter __result, _Tp*)
{
//萃取出迭代器result的value type
//然后判断该value type是否为POD,关于POD会在另一篇文章中详细解释
//编译器会将_Is_POD()的结果,作参数推导
//__uninitialized_copy_aux定义在上面
typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;
return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());
}
//uninitialized_copy将内存的配置与对象的构造行为分离开来
//C++标准规格书要求uninitialized_copy具有"commit or rollback"语义
//即要么构造出所有必要元素,要么当有任何一个copy construct失败时,就不构造任何东西
//迭代器__first指向输入端的起始位置
//迭代器__last指向输入端的结束位置,前闭后开区间
//迭代器__result指向输出端的起始处,即欲初始化的起始处
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
uninitialized_copy(_InputIter __first, _InputIter __last,
_ForwardIter __result)
{
//利用__VALUE_TYPE()取出__result的value type
//__uninitialized_copy定义在上面
return __uninitialized_copy(__first, __last, __result,
__VALUE_TYPE(__result));
}
//stl\Stl_construct.h
template <class _T1, class _T2>
inline void _Construct(_T1* __p, const _T2& __value) {
//构造以T1为类型,值为__value的元素
new ((void*) __p) _T1(__value);
}
//stl\Stl_construct.h
template <class _Tp>
inline void destroy(_Tp* __pointer) {
_Destroy(__pointer);
}
//析构并释放元素与内存
template <class _ForwardIterator>
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
//_Destroy定义在下面
_Destroy(__first, __last);
}
//stl\Stl_construct.h
template <class _Tp>
inline void _Destroy(_Tp* __pointer) {
//调用每个迭代器所指数据类型的析构函数
__pointer->~_Tp();
}
//如果为__false_type,即non-trivial destructor,那么就遍历整个范围,对每一个对象都调用一个参数的destroy()
template <class _ForwardIterator>
void
__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
//遍历整个范围,依次析构每个对象
//destroy定义在上面
for ( ; __first != __last; ++__first)
destroy(&*__first);
}
//如果为__true_type,即trivial destructor,那么析构其实什么都不做
template <class _ForwardIterator>
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}
template <class _ForwardIterator, class _Tp>
inline void
__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*)
{
//判断元素的数值类型value type是否有trivial destructor
//准备将[first, last)范围内的所有对象析构,但不知道这个范围有多大
//如果很大的话,而每一个对象的析构函数都是trivial destructor,那么每一次调用都是对效率的伤害
//所以使用了value_type()获取了迭代器所指对象的类型
//再利用__type_traits<_Tp>判断该类型的析构函数是否为trivial destructor
//根据__type_traits<_Tp>选择最合适的析构方法
typedef typename __type_traits<_Tp>::has_trivial_destructor
_Trivial_destructor;
//__destroy_aux定义在上面
__destroy_aux(__first, __last, _Trivial_destructor());
}
template <class _ForwardIterator>
inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) {
//使用__VALUE_TYPE获取迭代器__first所指对象的value type
//__destroy定义在上面
__destroy(__first, __last, __VALUE_TYPE(__first));
}
* 码完收工。。。一会把POD和trivial destruct总结一下。。。→_→ *
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!