vector源码阅读笔记(初始化)
2013-10-24 11:24
746 查看
vector类的继承关系是这样的:
class vector → class _Vector_val → struct _Container_base12
其中,_Container_base12中只有一个成员变量:
这个结构体包含两个变量:
其中的_Myfirstiter结构为:
这个结构体非常类似于一个链表,存储不同的_Container_proxy对象的指针。
而class _Vector_val中有4个成员变量:
前三个pointer类型变量就是vector中用来标记内存空间起点、当前可用存储位置与内存空间终点。
_Alval的类型是:
(个人表示没看懂,不过看函数实现与注释,这个变量用来申请新对象)
至于class vector,个人表示未在vector中找到成员变量。看看基类的定义,也就用了这些。
好嘞,现在开始初始化!
默认构造函数会调用_Mybase()即它父类的默认构造函数(其实父类也就一个构造函数,只是有默认传参),代码如下:(有条件编译,但是不懂具体条件编译的条件,就不分别分析了)
我这里调用的是#else中的代码,初始化一个_Alloc的对象,并赋值给_Alval。然后使用这个对象初始化_Myproxy,使其指向一个空的_Container_proxy对象(代码在上面)。然后将三个指针均指向NULL。
若初始化vector的时候传入了_Alloc对象类型的参数_Al(因为加了explicit关键字,所以不允许自动类型转换),
则将_Al传参给_Mybase(_Al),其余一样。
若以size_type类型的传参初始化vector,
则按照无传参的方式对_Mybase()传参,初始化父类指针与_Myproxy后,调用resize(_Count),为当前vector申请大小为_Count的内存空间。(resize(size_type)相关会另开帖子)
若以size_type及_Ty对象初始化vector,
则初始化父类后,尝试申请_Count的空间,若成功,则通过一系列的函数调用,从_Myfirst开始,在vector中存储_Count个对象。
这个构造函数与上一个类似:
至于拷贝构造函数,使用的是const的引用传参
先申请传参对象_Right同样大小的空间,然后从_Right._Myfirst到_Right._Myend拷贝数据(使用对象的拷贝构造函数)。
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拷贝数据(使用对象的拷贝构造函数)。
相关文章推荐
- SDL源码阅读笔记(2) video dirver的初始化及选择
- tomcat源码阅读笔记二——初始化过程(下)
- 源码阅读笔记 – 2 std::vector (2) 关于Allocator Aware Container特性
- SDL源码阅读笔记(2) video dirver的初始化及选择
- tomcat源码阅读笔记二——初始化过程(上)
- Spark源码阅读笔记:DriverProgram初始化
- Nginx 源码阅读笔记5 初始化 cycle
- Nginx 源码阅读笔记9 http 模块初始化
- JAVA 集合类(java.util)源码阅读笔记------Vector
- SDL源码阅读笔记(2) video dirver的初始化及选择
- 源码阅读笔记 – 2 std::vector (1)
- 早前阅读live555源码做的笔记
- Tensorflow object detection API 源码阅读笔记:Mask R-CNN
- LZ77源码阅读笔记
- CI框架源码阅读笔记8 控制器Controller.php
- HSF源码阅读笔记(二)
- thinking in java 阅读笔记 第四章 初始化和清除
- libevent源码阅读笔记——通用时间队列
- [置顶] nginx源码阅读(二).初始化:main函数及ngx_init_cycle函数
- apache1.3.39源码alloc.c阅读笔记