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的更多相关文章

  1. STL源码剖析读书笔记--第四章--序列式容器

    1.什么是序列式容器?什么是关联式容器? 书上给出的解释是,序列式容器中的元素是可序的(可理解为可以按序索引,不管这个索引是像数组一样的随机索引,还是像链表一样的顺序索引),但是元素值在索引顺序的方向 ...

  2. Stl源码剖析读书笔记之Alloc细节

    阅读基础: Foo *pf = new Foo; 执行了两个步骤: 1)::operator new 向系统申请内存. 2) 调用Foo::Foo()构造函数构造实例.  ==> 申请内存,构造 ...

  3. STL源码剖析读书笔记--第6章&第7章--算法与仿函数

    老实说,这两章内容还蛮多的,但是其实在应用中一点点了解比较好.所以我决定这两张在以后使用过程中零零散散地总结,这个时候就说些基本概念好了.实际上,这两个STL组件都及其重要,我不详述一方面是自己偷懒, ...

  4. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  5. c++ stl源码剖析学习笔记(一)uninitialized_copy()函数

    template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...

  6. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  7. 重温《STL源码剖析》笔记 第三章

    源码之前,了无秘密. --侯杰 第三章:迭代器概念与traits编程技法 迭代器是一种smart pointer auto_Ptr 是一个用来包装原生指针(native pointer)的对象,声明狼 ...

  8. 重温《STL源码剖析》笔记 第五章

    源码之前,了无秘密  ——侯杰 序列式容器 关联式容器 array(build in) RB-tree vector set heap   map priority-queue multiset li ...

  9. 重温《STL源码剖析》笔记 第一章

    源码之前,了无秘密. --侯杰 经典的书,确实每看一遍都能重新收获一遍: 第一章:STL简介 STL的设计思维:对象的耦合性极低,复用性极高,符合开发封闭原则的程序库. STL的价值:1.带给我们一套 ...

随机推荐

  1. 开发人员应该知道的SEO

    搜索引擎是如何工作的 > 如果你有时间,可以读一下谷歌的框架: http://infolab.stanford.edu/~backrub/google.html > 这是一个老的,有些过时 ...

  2. 关于qt学习的一点小记录(1)

    今日为了应付学校作业要求 决定现学qt来制作界面 毕竟c++不像在这方面c#可以那么方便 qt主要依靠信号.槽来实现类似winform中的消息 鉴于要尽快做完,故而没有细看qt 只是大概了解了下界面的 ...

  3. 计算机程序的思维逻辑 (63) - 实用序列化: JSON/XML/MessagePack

    上节,我们介绍了Java中的标准序列化机制,我们提到,它有一些重要的限制,最重要的是不能跨语言,实践中经常使用一些替代方案,比如XML/JSON/MessagePack. Java SDK中对这些格式 ...

  4. 【转】P2P之UDP穿透NAT的原理与实现(附源代码)

    作者:shootingstars (有容乃大,无欲则刚)  日期:2004-5-25 出处:P2P中国(PPcn.net) P2P 之 UDP穿透NAT的原理与实现(附源代码)原创:shootings ...

  5. Direct3D 光照和材质

      今天我们来学习下Direct3D里面的光源和材质. 四大光照类型: 环境光 Ambient Light 一个物体没有被光照直接照射,通过每一些物体反射的光线到达这个物体,它也有可能被看到.这种称为 ...

  6. Hibernate框架增删改查测试类归为一个类

    package cn.happy.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org ...

  7. 分割视图控制器(UISplitViewController) 改_masterColumnWidth 导致在 IOS 10中出现闪退

    默认UISplitViewController的Master和Detail的宽度是固定的,可以通过下面的方式来改变 [splitViewController setValue:[NSNumber nu ...

  8. C#软件开发实例.私人订制自己的屏幕截图工具(七)加入放大镜的功能

    上一篇:C#软件开发实例.私人订制自己的屏幕截图工具(六)加入配置管理功能 因为截图时可能须要精确截取某一部分,所以须要放大镜的功能,这样截取的时候才更easy定位截图的位置. 加入PictureBo ...

  9. sql语句中查询出的数据添加一列,并且添加默认值

    查询出数据,并且要添加一列表中都不存在的数据,且这一列的值都是相等的 select app_id,app_secret from wx_ticket group by app_id; 查询出的数据是 ...

  10. JAVA设计模式-工厂模式(代码示例)

    结构 MySort.java 实际业务中我们可能会使用任意一种排序方法 package pers.zander.edu.arithmetic.sort; /** * 排序接口 * @author * ...