一、程序代码:
#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()); }