1.Bitset
此类主要用于位存储,如果单纯的记录bool状态,个人认为其实可以完全可以通过左移右移操作符号(<<,>>)得到对应的状态。如果状态非常长的话,还是用bitset吧。
源码就不贴出来了,非常简单。上面是vs2010验证的bitset的调试过程,需要观察注意下面几点
- 构造函数:bit仓库中bit分布位(大端模式,高位存在低位)
- reset:把1->0的操作,不会把0->1.
- set:可以把某元素设置位0,或1.
2. vector
2.1 vecotor元素地址是连续
vector存放的是地址连续对象,其大小为根据需要自动边长(默认2倍速度)。开始默认为4个元素,如果继续添加元素,则会先申请8个元素的内存,将前面4个元素拷贝过来,然后释放旧的4快缓冲。
- 由addr记录地址可以看到,地址是连续增加的。
- 正序迭代器一开始指向第一个元素地址,最后指向最后元素后面那块内存的首地址
- 逆序迭代器一开始指向最后一个元素首地址,最后指向第一个元素后面那块内存首地址
- 从下面打印结果也能看出正序访问和逆序访问,地址忘记修改了,打印的是数组的地址,心里明白即可。
2.2 vector 元素个数确认
- 一开始vec中已经保存了3个元素,所以刚开始size=3,capacity=3,max_size:很大
- 紧接着往里面继续push6,7,然后size=5,capacity=6,这里为什么是6,而不是5.原因就是根据之前的size*2,其实到底每次容量增大多少,由vector内部逻辑来处理。了解即可,如果向搞明白,努力撸撸源码吧。
上面记录了一组vector能力的变化过程。 - 一开始capacity就是一开始预留的大小,可见第一次循环结束后capacity=3.
- 紧接着第二次循环执行完后,capacity=4,即总共push了4个元素,但是capacity没有较大增长,反而是+1增长
- 第4次循环结束后,capacity=9,如果还是+1增长,那么这次capacity应该等于8才对。可见没有进行+1增长。
- 第5次之后就不是+1增长了。
##2.3 vecotor 设置大小方法介绍
- reserve(): reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size.
- capacity():返回当前已分配内存,最大能存放的数量
- size():返回当前已经push到vector的元素个数
- 当capacity增大的一定数量后,再把size设置小,此时不会释放之前申请的内存(毕竟申请连续buffer不容易)。
2.4 vecotor 访问元素的方法
不多说,都在动图中。
2.5 vector修改元素的方法
2.5.1 asign
- begin():返回元素首地址
- end():返回最后一个元素末尾的位置,以
first.assign (7,99)
为例子,那么第8个元素的首地址,应该下图中的addr,但是end()返回的是第8个元素后面空间的首地址,该地址可能指向了无效的地址,如果capacity>size,则不会指向无效地址
begin addr end
| \ |
v v v
|-0--|--1--|--2--|--3--|--4--|--5--|--6--|--7--|--8--|----|----|
2.5.2 insert
insert的方法如下所示:
iterator insert ( iterator position, const T& x );
void insert ( iterator position, size_type n, const T& x );
template <class InputIterator>
void insert ( iterator position, InputIterator first, InputIterator last );
实例演示:
vector释放元素的方法
iterator erase ( iterator position );
iterator erase ( iterator first, iterator last );
- 移除过程中,不会直接释放内存,只是把数据往前移动了一下。可以从addr的数组中看出这个道理。