您的位置:首页 > 其它

vector源码阅读笔记(初始化)

2013-10-24 11:24 696 查看
vector类的继承关系是这样的:

class vector → class _Vector_val → struct _Container_base12

其中,_Container_base12中只有一个成员变量:

struct _Container_proxy *_Myproxy;

这个结构体包含两个变量:

struct _Container_proxy
	{	// store head of iterator chain and back pointer
	_Container_proxy()
		: _Mycont(0), _Myfirstiter(0)
		{	// construct from pointers
		}
	const _Container_base12 *_Mycont;
	_Iterator_base12 *_Myfirstiter;
	};

其中的_Myfirstiter结构为:

struct _Iterator_base12
	{	// store links to container proxy, next iterator

        _Container_proxy *_Myproxy;
        _Iterator_base12 *_Mynextiter;
};


这个结构体非常类似于一个链表,存储不同的_Container_proxy对象的指针。

而class _Vector_val中有4个成员变量:

pointer _Myfirst;	// pointer to beginning of array
pointer _Mylast;	// pointer to current end of sequence
pointer _Myend;	// pointer to end of array
_Alty _Alval;	// allocator object for values

前三个pointer类型变量就是vector中用来标记内存空间起点、当前可用存储位置与内存空间终点。

_Alval的类型是:

typedef typename _Alloc::template rebind<_Ty>::other _Alty;

(个人表示没看懂,不过看函数实现与注释,这个变量用来申请新对象)

至于class vector,个人表示未在vector中找到成员变量。看看基类的定义,也就用了这些。

好嘞,现在开始初始化!

默认构造函数会调用_Mybase()即它父类的默认构造函数(其实父类也就一个构造函数,只是有默认传参),代码如下:(有条件编译,但是不懂具体条件编译的条件,就不分别分析了)

#if _ITERATOR_DEBUG_LEVEL == 0
	_Vector_val(_Alloc _Al = _Alloc())
		: _Alval(_Al)
		{	// construct allocator from _Al
		_Myfirst = 0;
		_Mylast = 0;
		_Myend = 0;
		}

	~_Vector_val()
		{	// destroy proxy
		}

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
	_Vector_val(_Alloc _Al = _Alloc())
		: _Alval(_Al)
		{	// construct allocator from _Al
		typename _Alloc::template rebind<_Container_proxy>::other
			_Alproxy(_Alval);
		this->_Myproxy = _Alproxy.allocate(1);
		_Cons_val(_Alproxy, this->_Myproxy, _Container_proxy());
		this->_Myproxy->_Mycont = this;

		_Myfirst = 0;
		_Mylast = 0;
		_Myend = 0;
		}

	~_Vector_val()
		{	// destroy proxy
		typename _Alloc::template rebind<_Container_proxy>::other
			_Alproxy(_Alval);
		this->_Orphan_all();
		_Dest_val(_Alproxy, this->_Myproxy);
		_Alproxy.deallocate(this->_Myproxy, 1);
		this->_Myproxy = 0;
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

我这里调用的是#else中的代码,初始化一个_Alloc的对象,并赋值给_Alval。然后使用这个对象初始化_Myproxy,使其指向一个空的_Container_proxy对象(代码在上面)。然后将三个指针均指向NULL。

若初始化vector的时候传入了_Alloc对象类型的参数_Al(因为加了explicit关键字,所以不允许自动类型转换),

explicit vector(const _Alloc& _Al)
		: _Mybase(_Al)
		{	// construct empty vector with allocator
		}


则将_Al传参给_Mybase(_Al),其余一样。

若以size_type类型的传参初始化vector,

explicit vector(size_type _Count)
		: _Mybase()
		{	// construct from _Count * _Ty()
		resize(_Count);
		}

则按照无传参的方式对_Mybase()传参,初始化父类指针与_Myproxy后,调用resize(_Count),为当前vector申请大小为_Count的内存空间。(resize(size_type)相关会另开帖子)

若以size_type及_Ty对象初始化vector,

vector(size_type _Count, const _Ty& _Val)
		: _Mybase()
		{	// construct from _Count * _Val
		_Construct_n(_Count, _STD addressof(_Val));
		}

则初始化父类后,尝试申请_Count的空间,若成功,则通过一系列的函数调用,从_Myfirst开始,在vector中存储_Count个对象。

这个构造函数与上一个类似:

vector(size_type _Count, const _Ty& _Val, const _Alloc& _Al)
		: _Mybase(_Al)
		{	// construct from _Count * _Val, with allocator
		_Construct_n(_Count, _STD addressof(_Val));


至于拷贝构造函数,使用的是const的引用传参

vector(const _Myt& _Right)
		: _Mybase(_Right._Alval)
		{	// construct by copying _Right
		if (_Buy(_Right.size()))
			_TRY_BEGIN
			this->_Mylast = _Ucopy(_Right.begin(), _Right.end(),
				this->_Myfirst);
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
		}

先申请传参对象_Right同样大小的空间,然后从_Right._Myfirst到_Right._Myend拷贝数据(使用对象的拷贝构造函数)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: