STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector
1.vector概述
vector是一种序列式容器,我的理解是vector就像数组。但是数组有一个很大的问题就是当我们分配
一个一定大小的数组的时候,起初也许我们不会觉得数组容量太小不合需求,但是随着数据量的增加,
数组尺寸大小不再满足需求,此时我们需要手动的去扩展其大小。然而vector就帮我们完全实现了一个可
自适应增长的数组功能。那么这样看来vector其实也就是一种可自适应增长的动态数组的类的实现。
2.关于vector的定义
其实用过vector的人都知道 vector的定义大都像这个样子:
vector<int> v1;
vector<sting> v2;
很显然vector是一种与类型无关的类模板,支持各种类型的vector,这也很好的体现了C++的泛型思想,正
是这种类型无关性,使得STL在各种平台上广为使用。
这里我只是贴出STL源码剖析书中一小部分vector定义
template <class T,class Alloc=alloc>
class vector
{
public:
typedef T value_type;
typedef valuetype* pointer;
typedef valuetype* iterator;
typedef valuetype& reference;
typedef size_t size_type;
......
protected:
iterator start;
iterator finish;
iterator end_of_storage;
....
pubic:
iterator begin{return start;}
iterator end(){return finish;}
size_type size() const {return size_type(end()-begin());}
size_type capacity() const {return size_type(end_of_storage-begin());}
reference front {return *begin()}
}
上面有几个关键点:
vector维护了三个迭代器:start,finish和end_of_storage由typedef valuetype* iterator可知迭代器说白
了就是指针。那么vector维护的三个迭代器(指针)的意思是什么呢。start指向vector的第一个元素。finish
指向vector已经使用的空间的最后一个元素的下一个元素。end_of_storage指向vector总共可用空间的最后
一个元素的下一个元素所以操作vector与操作指针完全类似,只是在vector中把这些操作封装成相应的方法
直接供读者使用罢了。
3.vector内存分配原理
不是之前我们说vector是一种自增长的动态数组吗?那么其子增长的原理是什么。
其实很简单:
1.当vector为空时,我们插入一个元素到vector中,这时候vector将内存容量变为1,然后将新的元素插入其中
2.当vector容量为1的时候,此时vector中刚好有一个元素,若要插入一个2,这时候将重新new一个内存为2的新空
间,将之前内存中的1拷贝到新内存并释放1旧内存,同时将新的元素2插入其中
3.重复步骤2,只要就内存容量已满就重新分配新内存,新内存的大小是旧内存的二倍,再讲旧内存中的数据赋
值到新内存,同时释放新内存。同时插入新元素在新的内存空间。
我们可以用下面的程序验证这一点:
#include <iostream>
#include <vector>
using namespace std; int main(int argc, char* argv[])
{
std::vector<int> v1; cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
v1.push_back();
cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
v1.push_back();
cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
v1.push_back();
cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
v1.push_back();
cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
v1.push_back();
cout<<"v1.size()="<<v1.size()<<" "<<"v1.capacity()="<<v1.capacity()<<endl;
return ;
}
截图如下:
此外,有几个问题需要注意:
1.为什么vector容量满了之后要重新开辟新的内存,因为vector要求连续的内存空间
2.如果重新开启新内存太频繁应该会造成较大的程序开销,怎么办.我们可以一开给reserve一个大的capacity.
3.重新开启新内存是否会造成原来的迭代器失效 ?是的,所以我们最好知道何时会开辟新的capacity,进而防止这种迭代器失效。
4.对于vector删除或者插入造成的迭代器失效已经在之前的博文中有介绍。
STL源码剖析读书笔记之vector的更多相关文章
- STL源码剖析读书笔记--第四章--序列式容器
1.什么是序列式容器?什么是关联式容器? 书上给出的解释是,序列式容器中的元素是可序的(可理解为可以按序索引,不管这个索引是像数组一样的随机索引,还是像链表一样的顺序索引),但是元素值在索引顺序的方向 ...
- Stl源码剖析读书笔记之Alloc细节
阅读基础: Foo *pf = new Foo; 执行了两个步骤: 1)::operator new 向系统申请内存. 2) 调用Foo::Foo()构造函数构造实例. ==> 申请内存,构造 ...
- STL源码剖析读书笔记--第6章&第7章--算法与仿函数
老实说,这两章内容还蛮多的,但是其实在应用中一点点了解比较好.所以我决定这两张在以后使用过程中零零散散地总结,这个时候就说些基本概念好了.实际上,这两个STL组件都及其重要,我不详述一方面是自己偷懒, ...
- STL源码分析读书笔记--第二章--空间配置器(allocator)
声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...
- c++ stl源码剖析学习笔记(一)uninitialized_copy()函数
template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...
- (原创滴~)STL源码剖析读书总结1——GP和内存管理
读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...
- 重温《STL源码剖析》笔记 第三章
源码之前,了无秘密. --侯杰 第三章:迭代器概念与traits编程技法 迭代器是一种smart pointer auto_Ptr 是一个用来包装原生指针(native pointer)的对象,声明狼 ...
- 重温《STL源码剖析》笔记 第五章
源码之前,了无秘密 ——侯杰 序列式容器 关联式容器 array(build in) RB-tree vector set heap map priority-queue multiset li ...
- 重温《STL源码剖析》笔记 第一章
源码之前,了无秘密. --侯杰 经典的书,确实每看一遍都能重新收获一遍: 第一章:STL简介 STL的设计思维:对象的耦合性极低,复用性极高,符合开发封闭原则的程序库. STL的价值:1.带给我们一套 ...
随机推荐
- A星算法
没有采用二叉堆算法优化, 学习了几天终于搞除了一个demo, 这个列子如果点击按钮生成的方块大小不正确,可以先设置下预设调成相应的大小 只能上下左右走 using UnityEngine; usi ...
- 动态载入TreeView时让TreeView节点前显示加号
解释下标题,我这里通过webservice获取数据并动态载入TreeView节点.那么某个节点展开前它是没有子节点的.那么它就不显示加号.这样会让用户误以为此节点不能展开.我是这样做的,每次创建节点a ...
- maven报错cannot change version of project facet
用Eclipse创建Maven结构的web项目的时候选择了默认的catalog,由于这个catalog比较老,用的servlet还是2.3,而现在最少也是2.5,所以经常会出现问题,在Projecdt ...
- Python进阶之路---1.1python简介
Python简介 Python简介 Python (发音:[ 'paiθ(ə)n; (US) 'paiθɔn ]n.蟒蛇,巨蛇 ),是一种面向对象的解释 ...
- oracle 临时表空间的增删改查
oracle 临时表空间的增删改查 oracle 临时表空间的增删改查 1.查看临时表空间 (dba_temp_files视图)(v_$tempfile视图)select tablespace_nam ...
- mysql免安装版配置与使用方法
mysql免安装版配置与使用方法 以mysql-noinstall-5.1.6(win32)为例 1>把压缩文件mysql-noinstall-5.1.6-alpha-win32.zi ...
- Android Studio 导入Eclipse工程
eclipse:workspace对应多个project:而android studio是project对应多个module:故,在android studio中的工程project实际上是eclip ...
- Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.
I have installed a Web application on IIS 7.0 windows server 2008 R2 64 bit OS I am refering a oracl ...
- 在现代渲染API下,封装跨平台渲染框架的尝试 - 资源管理
小生资历浅薄,不讨论该主题的重要性与未来的意义,只是个人兴趣爱好平日对这个问题思考了很多,总觉得要写点东西记录下来.框架还没有定型,只是记录自己设计的过程. 系统要跨平台,首先得将平台相关的实现与平台 ...
- jquery获取当前鼠标所在位置的坐标
$(document).ready(function(){ $(document).mousemove(function(e){ $('#xy').html("X :"+e.pag ...