一、程序代码:
#include <vector>
using namespace std;
int main()
{
vector<int> vec(20);
return 1;
}
二、分析:
调用如下构造函数:
explicit vector(size_type _Count) : _Mybase()
{ // construct from _Count * _Ty()
_Construct_n(_Count, _Ty());
}
这个构造函数是显示构造函数,以防止隐式类型转换而发生歧义。_Construct_n负责分配内存,然后构造元素。
void _Construct_n(size_type _Count, const _Ty& _Val)
{
if (_Buy(_Count)) // 申请内存区,这时内存区还没有初始化
{
try{ // 使用_Val来填充内存区
_Mylast = _Ufill(_Myfirst, _Count, _Val);
}catch(...){
_Tidy();
throw;
}
}
}
typedef typename _Alloc::const_pointer pointer是vector中的定义,则pointer其实是int *的别名
// vector 1206
int * _Ufill(int * _Ptr, size_t _Count, const int &_Val)
{ // copy initializing _Count * _Val, using allocator
::stdext::unchecked_uninitialized_fill_n(_Ptr, _Count, _Val, this->_Alval);
return (_Ptr + _Count);
}
unchecked_uninitialized_fill_n有两个,另一个比这个函数多一个内存配置器参数
// memory 723行
inline void unchecked_uninitialized_fill_n(int * _First, size_t _Count,
const int& _Val, allocator<int>& _Al)
{ // copy _Count *_Val to raw _First, using _Al
::std::_Uninit_fill_n(_First, _Count, _Val, _Al,
::std::_Ptr_cat(_First, _First), ::std::_Range_checked_iterator_tag());
}
_Ptr_cat的推导:_First是int *类型,则_Ptr_cat函数返回的是_Ptr_cat_helper<int*, int*>::_Ptr_cat类型。在xutility文件中定义有int*类型的_Ptr_cat_helper模板, 可见返回结果是一个_Scalar_ptr_iterator_tag类型,标识指针所指是一个标量类型。
调用_Scalar_ptr_iterator_tag版本的带空间配置器的_Uninit_fill_n函数。
// memory 321行
inline void _Uninit_fill_n(int *_First, size_t _Count, const int& _Val
,allocator<int>&, _Scalar_ptr_iterator_tag, _Range_checked_iterator_tag)
{ // copy _Count *_Val to raw _First, scalar type
::stdext::unchecked_fill_n(_First, _Count, _Val);
}
调用unchecked_fill_n函数。
// xutility 3035行
template<class _OutIt, class _Diff, class _Ty> inline
inline void unchecked_fill_n(int * _First, size_t _Count, const int& _Val)
{ // copy _Val _Count times through [_First, ...)
::std::_Fill_n(_First, _Count, _Val, ::std::_Iter_cat(_First)
, ::std::_Range_checked_iterator_tag());
}
_Iter_cat推导:_First是int*类型,调用iterator_traits<_Ty *>这个模板,返回的类型是random_access_iterator_tag。
接下来有两种调用可能,要看_SECURE_SCL的取值,在这个程序中该值是1
// xutility 2812
#if _SECURE_SCL
void _Fill_n(int * _First, size_t _Count, const int& _Val
, random_access_iterator_tag, _Range_checked_iterator_tag)
{
_Fill_n(::std::_Checked_base(_First), _Count, _Val,
_Range_checked_iterator_tag());
}
#endif
_Checked_base(int *)推导:_Checked_iterator_base_helper<int *> --> _Checked_iterator_base_helper2<int *, false> --> _Checked_iterator_base_helper1<int *, _Unchanged_checked_iterator_base_type_tag> 则int * 为_Checked_iterator_base_type类型
// xutility 2758
inline void _Fill_n(int * _First, size_t _Count, const int& _Val,
_Range_checked_iterator_tag)
{ // copy _Val _Count times through [_First, ...)
for (; 0 < _Count; --_Count, ++_First)
*_First = _Val;
}
_SECURE_SCL为0的情况:
源代码:
#define _SECURE_SCL 0
#include <vector>
using namespace std;
int main()
{
vector<int> vec(20);
return 1;
}
倒数第二个调用的函数将是如下函数:
// xutility 2804
inline void _Fill_n(int * _First, size_t _Count, const int& _Val,
random_access_iterator_tag, _Range_checked_iterator_tag)
{
_Fill_n(_First, _Count, _Val, _Range_checked_iterator_tag());
}