《stl源码剖析》学习笔记 1.vector
来源:互联网 发布:javascript字符串替换 编辑:程序博客网 时间:2024/06/05 07:43
1.因为vector开辟的是一段连续的堆内存,所以迭代器无需单独定义,用普通指针就行。
typedef T value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef value_type *iterator;//iterator=pointer
typedef size_t size_type;
typedef ptrdiff_t difference_type;
2.空间适配器。将alloc作为默认模板参数。
template<class T, class Alloc = alloc>
class vector
{
protected:
typedef simple_alloc<value_type, Alloc> data_allocator;
...
};
以后进行allocate和deallocate时通过data_allocator来访问就ok。
3.内存控制。因为效率因素,不能每次使用多少就开辟多少,这样的话每次使用都得经历开辟新空间,复制数据,释放原空间的过程,效率很低,有时会多开辟空间(双倍空间)所以用start,finish,end_of_storge三个指针来控制内存。start表示已开辟内存的首地址,finish表示已使用的空间末端,end_of_storge表示已开辟的内存末端(stl一般使用前闭后开的方式)。
4.构造函数。
vector(): start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const T &value) { fill_initialize(n, value); }
vector(int n, const T &value) { fill_initialize(n, value); }
vector(long n, const T &value) { fill_initialize(n, value); }
explicit vector(size_type n) { fill_initialize(n, T()); }
没什么特别的,一般就这三种定义方式。
vector<int> s; vector<int> s(10, 4); vector<int> s(10);
它通过fill_initialize函数来实现分配空间,填充元素。
void fill_initialize(size_type n, const T &value)
{
start = allocate_and_fill(n, value);
finish = start + n;
end_of_storage = finish;
}
5.push_back(),pop_back。push_back是向末尾插入新元素,想下原理,就是判断是否还有未使用空间,如果有,那么直接在finish上构造新元素,然后++finish。
如果finish==end_of_storge了,那么开辟一段双倍的空间,然后复制原来的元素,再构造需要插入的元素,最后释放原来的空间。下次push_back时,因为刚已经开辟了多余的空间,所以直接构造新元素,移动指针就ok。 pop_back时将finish指针前移一位,然后调用析构函数。
6.erase函数。两个版本,一个是erase一个位置,另一个是erase一个区间。看代码吧。
iterator erase(iterator position)
{
if (position + 1 != end())
{
//把position+1 到finish 的数据复制到position
copy(position + 1, finish, position);
}
--finish;
destroy(finish);
return position;
}
iterator erase(iterator first, iterator last)
{
//把last到finish的数据复制到first
iterator i = copy(last, finish, first);
//析构多余的空间
destroy(i, finish);
finish = finish - (last - first);
return first;
}
7.insert函数(个人觉得这个函数写的最精妙)。
//在position位置插入n个x
void insert(iterator position, size_type n, const T &x)
{
if (n != 0)
{
//如果未使用的空间大于n,则不用另觅空间,否则得另觅空间。
if (size_type(end_of_storage - finish) >= n)
{
T x_copy = x;
const size_type elems_after = finish - position;
iterator old_finish = finish;
//插入端到末尾的元素个数大于n情况 比如现在vector容量20,
使用10个空间,放置0 1 2 3 4 5 6 7 8 9然后在1的位置
插入5个10,elems_after = 10-1=9,就是说从插入点到末尾有9个空间,先复制5-9到位置10开始的空间,变成012345678956789,finish=16,然后将1234复制到原来9-6的位置(从后向前复制),变成012345123456789,然后将位置1-5填充5个10.
插入端到末尾的元素个数小于n情况,比如说现在在8的位置插入5个10,elems_after=3,先在位置10到12填充3个10,0123456789 10 10 10,然后复制89,变成0123456789 10 10 10 8 9 然后在89位置填充10 得到01234567 10 10 10 10 10 8 9
if (elems_after > n)
{
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
fill(position, position + n, x_copy);
}
else
{
uninitialized_fill_n(finish, n - elems_after, x_copy);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
fill(position, old_finish, x_copy);
}
}
else
{
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_fill_n(new_finish, n, x);
new_finish = uninitialized_copy(position, finish,new_finish);
destroy(start, finish);
deallcate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
- 《stl源码剖析》学习笔记 1.vector
- STL源码剖析:vector学习笔记
- STL学习笔记之容器--vector(二)源码剖析
- STL源码剖析笔记三vector
- stl vector源码剖析
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析vector
- STL源码剖析----vector
- STL源码剖析--vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析 --vector
- STL源码剖析---vector
- STL源码剖析--vector
- kafka+zookeeper安装
- oracle测试数据安装是否成功
- MongoDB学习笔记(三)--MongoDB的C#驱动的基本使用
- android 蓝牙BLE 开发
- elasticsearch学习笔记-安装与配置
- 《stl源码剖析》学习笔记 1.vector
- android studio internet连接本地服务器错误1
- 登陆oracle的三种方法
- ATC:go Thrift RPC 使用 (连接池)
- win7系统搭建PHP+Mysql+Apache环境+部署ecshop项目
- CDH遇到问题点滴记录
- 第二章 创建对话框
- Tensorflow之Basic word2vec代码详解(上)
- 如何查与给定时间最接近的一条信息