[vs 2005]vector的单参数构造流程

本文详细分析了VS 2005中vector的单参数构造过程,涉及构造函数、内存分配、元素初始化及 iterator 的类型推导。通过程序代码展示了构造过程中调用的内部函数,如_Construct_n、unchecked_uninitialized_fill_n和unchecked_fill_n等,揭示了Secure_SCL在不同设置下的行为差异。
摘要由CSDN通过智能技术生成

一、程序代码:

#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());
}








 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值