STL vector的内部实现原理及基本用法
来源:互联网 发布:qq三国79js单刷孟获 编辑:程序博客网 时间:2024/06/08 19:16
【原文:http://blog.csdn.net/u012658346/article/details/50725933】
本文基于STL vector源代码,但是不考虑分配器allocator,迭代器iterator,异常处理try/catch等内容,同时对_Ucopy()、 _Umove()、 _Ufill()函数也不会过度分析。
一、vector的定义
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
简单理解,就是vector是利用上述三个指针来表示的,基本示意图如下:
两个关键大小:
大小:size=_Mylast - _Myfirst;
容量:capacity=_Myend - _Myfirst;
分别对应于resize()、reserve()两个函数。
size表示vector中已有元素的个数,容量表示vector最多可存储的元素的个数;为了降低二次分配时的成本,vector实际配置的大小可能比客户需求的更大一些,以备将来扩充,这就是容量的概念。即capacity>=size,当等于时,容器此时已满,若再要加入新的元素时,就要重新进行内存分配,整个vector的数据都要移动到新内存。二次分配成本较高,在实际操作时,应尽量预留一定空间,避免二次分配。
二、构造与析构
1、构造
vector的构造函数主要有以下几种:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
vector优异性能的秘诀之一,就是配置比其所容纳的元素所需更多的内存,一般在使用vector之前,就先预留足够空间,以避免二次分配,这样可以使vector的性能达到最佳。因此元素个数_Count是个远比元素值 _Val重要的参数,因此当构造一个vector时,首要参数一定是元素个数。
由上各构造函数可知,基本上所有构造函数都是基于_Construct _n() 的
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
这样就完成了vector容器的构造了。
2、析构
vector的析构函数很简单,就是先销毁所有已存在的元素,然后释放所有内存
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
三、插入和删除元素
vector的插入和删除元素是通过push_ back () 、 pop_back()两个接口来实现的,他们的内部实现也非常简单
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
四、其他接口
1、reserve()操作
之前提到过reserve(Count) 函数主要是预留Count大小的空间,对应的是容器的容量,目的是保证(_Myend - _Myfirst)>=Count。只有当空间不足时,才会操作,即重新分配一块内存,将原有元素拷贝到新内存,并销毁原有内存
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
2、resize()操作
resize(Count) 函数主要是用于改变size的,也就是改变vector的大小,最终改变的是(_Mylast - _Myfirst)的值,当size < Count时,就插入元素,当size >Count时,就擦除元素。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3、_Insert_n()操作
resize()操作和insert()操作都会利用到_Insert_n()这个函数,这个函数非常重要,也比其他函数稍微复杂一点
虽然_Insert_n(_where, _Count, _Val ) 函数比较长,但是操作都非常简单,主要可以分为以下几种情况:
1、_Count == 0,不需要插入,直接返回
2、max_size() - size() < _Count,超过系统设置的最大容量,会溢出,造成Xlen()异常
- 3、_Capacity < size() + _Count,vector的容量不足以插入Count个元素,需要进行二次分配,扩大vector的容量。 在VS下,vector容量会扩大50%,即 _Capacity = _Capacity + _Capacity / 2;
若仍不足,则 _Capacity = size() + _Count;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
这种情况下,数据从原始容器移动到新分配内存时是从前到后移动的
4、空间足够,且被插入元素的位置比较靠近_Mylast,即已有元素的尾部
这种情况下不需要再次进行内存分配,且数据是从后往前操作的。首先是将where~last向后移动,为待插入数据预留Count大小的空间,然后从_Mylast处开始填充,然后将从where处开始填充剩余元素
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 5、空间足够,但插入的位置比较靠前
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4、erase()操作
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
主要操作就是将后半部分的有效元素向前拷贝,并将后面空间的无效元素析构,并更新_Mylast变量
5、assign()操作
assign()操作最终都会调用到下面的函数,主要操作是首先擦除容器中已有的全部元素,在从头开始插入Count个Val元素
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
五、基本使用
在经过上述对vector内部实现的分析后,再来理解相应接口就变得简单得多。
vector对外接口主要可以分为:
- 构造、析构:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 插入、删除、赋值
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 大小相关
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
- 获取迭代器
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 获取数据
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- STL vector的内部实现原理及基本用法
- STL vector的内部实现原理及基本用法
- STL vector基本用法
- [STL] vector基本用法
- [STL] vector基本用法
- 《STL系列》之vector原理及实现
- STL中vector的基本用法范例
- STL之vector的基本用法
- STL之Vector(一):Vector的基本用法
- (STL) vector的简单用法和实现
- STL——STL中vector的实现原理
- STL Vector的用法
- STL vector 的用法
- vector的用法及基本操作
- vector的内部实现
- STL之Vector实现原理
- C++中的STL之vector的超详细基本用法
- STL-vector的实现
- python操作mysql
- centos环境配置信息
- 基于二叉排序树的基本操作
- java中文汉字按英文字母表排序
- DTW的基本原理及其C语言实现
- STL vector的内部实现原理及基本用法
- 欢迎使用CSDN-markdown编辑器
- 微信小程序开发之弹出菜单
- mongoDB
- [XOR最小生成树 分治 Trie || Prim 堆] BNUOJ 52318 Be Friends
- The method getTextContent() is undefined for the type Node解决方法(eclipse)
- linux环境变量设置错误后的恢复方法(转)
- 数据结构之基于Java的二叉树实现
- vc 使用ShellExecut来启动控制面板中功能模块的操作