vector源码1(参考STL源码--侯捷):源码
vector源码1(参考STL源码--侯捷)
vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效
vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert
vector概述
Vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间纳入新元素,vector的使用效率,关键在于其对大小的控制以及重新配置时的元素迁移效率。
Vector定义摘要
template <class T,class Alloc=alloc>//alloc是SGI STL的空间配置器
class vector
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type* iterator;
typedef value_type& reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
typedef simple_alloc<value_type,Alloc> data_allocator;//simple_alloc是SGI STL的空间配置器
iterator start; //表示目前使用空间的头
iterator finish; //表示目前使用空间的尾
iterator end_of_storage; //表示目前可用空间的尾
void insert_aux(iterator position,const T& x);//插入元素,保护类型,对象不可调用
void deallocate(){
if(start)
/*为vector再分配空间为其原始可容纳空间的一倍,deallocate()函数如下:
*static void deallocate(T *p,size_t n)
{if(0!=n) Alloc::deallocate(p,n*sizeof(T));}
*/
data_allocator::deallocate(start,end_of_storage-start);
}
void fill_initialize(size_type n,const T& value){//用于vector初始赋值
start=allocate_and_fill(n,value);
finish=start+n;
end_of_storage=finish;
}
public:
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());}//当前可容纳元素
bool empty() const{return begin()==end();}//是否为空
reference operator[](size_type n){return *(begin()+n);}//定位元素,返回第n+1个元素
vector():start(0),finish(0),end_of_storage(0){}//初始化,如:vector<int> v;
/*size_type是STL类中定义的类型属性,用以保存任意string和vector类对象的长度,
以下都为初始化vector,如:vector<int> v(10,1)*/
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);}
//explit 防止隐式转换,此时初始化如:vector<int> v(10);
explicit vector(size_type n){fill_initialize(n,T());}
~vector(){ /*全局函数,destory()有两个版本,第一个版本接收一个指针,准备将该指针指向的对象析构掉;
第二个版本就是接收first和last两个迭代器(如下),将[first,last]下的对象析构掉。
在第二个版本下,如果析构对象的析构函数需要执行,会调用一个版本的destory(),否则直接
析构掉该对象,这里需要用到value_type()进行判断。
*/
destory(start,finish);
deallocate(); //vector的成员函数
}
reference front(){return *begin();}//返回第一个数
reference back(){return *(end()-1);}//返回最后一个数
void push_back(const T& x)//添加元素
{
if(finish !=end_of_storage){//是否超出最大可容纳空间
/*全局函数,construct()接收一个指针p和一个初值value,该函数的用途就是将
初值value设定到指针锁指的空间上。
*/
construct(finish,x);
++finish;
}
else{
insert_aux(end(),x); //vector的成员函数
}
}
void pop_back(){
--finish();
destroy(finish()); //调用第一类destory()函数,详细见上
}
iterator erase(iterator position){//擦除一个元素
if(position+1!=end())//不是擦除最后一个元素
copy(position+1,finish,position);//将元素前移,覆盖掉要擦除的元素
--finish;
destroy(finish);//销毁最后一个元素
return position;
}
void resize(size_type new_size(),const T& x){
if(new_size<size())
earse(begin()+new_size,end());//擦除掉第new_size()个数(0为第一个数)
else
insert(end(),new_size-size(),x);//用x补全vector长度为new_size()
}
void resize(size_type new_size) {resize(new_size,T());}//同上,补全数字为0
void clear(){earse(begin(),end());}//擦除所有元素
protected:
//配置空间,并填满内存
iterator allocate_and_fill(size_type n,const T& x){
iterator result=data_allocator::allocate(n);
/*全局函数,uninitialized_fill_n()有3个参数:
*迭代器first指向欲初始化空间的地址的起始处
*初始化空间的大小n
*初始化的值x
*/
uninitialized_fill_n(result,n,x);
return result;
}
};
vector源码1(参考STL源码--侯捷):源码的更多相关文章
- vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷):空间分配.push_back vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 v ...
- vector源码2(参考STL源码--侯捷):空间分配、push_back
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...
- list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构
list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...
- list源码2(参考STL源码--侯捷):constructor、push_back、insert
list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...
- list源码4(参考STL源码--侯捷):transfer、splice、merge、reverse、sort
list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...
- list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique
list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...
- STL 源码分析 (SGI版本, 侯捷著)
前言 源码之前,了无秘密 algorithm的重要性 效率的重要性 采用Cygnus C++ 2.91 for windows cygwin-b20.1-full2.exe 下载地址:http://d ...
- vector源码(参考STL源码--侯捷):空间分配导致迭代器失效
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...
- 侯捷STL课程及源码剖析学习2: allocator
以STL 的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container)的背后,默默工作默默付出. 一.分配器测试 测试代码 #include < ...
随机推荐
- Linq高级应用
Linq的应用为我们带来了很大的方便,提高了coding效率,最近看到了一个用linq写的数独游戏算法,让我看到了Linq写的是如此优雅,耳目一新的感觉,以前没有写过这样的代码,同时也感觉到原来Lin ...
- 写了十年JS却不知道模块化为何物?
作者:肖光宇 野狗科技联合创始人,先后在猫扑.百度.搜狗任职,爱折腾的前端工程师. 野狗官博:https://blog.wilddog.com/ 野狗官网:https://www.wilddog.co ...
- 获取当前操作的IFrame对象的方法
分两种情况:第一种:获取JS函数在父页面上,如下 function getIframeByElement(element){ var iframe; $("iframe").eac ...
- js中如何将数据获得2位小数以及对数据进行千分位划分
js中toFixed(n) 方法可把 数字四舍五入为指定小数位数n的数字,注意:这个方法只能对数据类型为Number的数据起作用,包括float,int等.例如: 123.12345.toFixe ...
- C++编译器详解(三)函数调用的区别:_cdecl以及_stdcall
1._stdcall是Pascal程序的缺省调用方式,通常用于Win32 API中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上&qu ...
- python基础回顾
1.第二个缺点就是代码不能加密.如果要发布你的Python程序,实际上就是发布源代码,这一点跟C语言不同,C语言不用发布源代码,只需要把编译后的机器码(也就是你在Windows 上常见的xxx.exe ...
- Java应用分类
Java应用分类 一.应用程序.指在操作系统上直接运行的,不是浏览器,Java环境用本机的,需要在客户端安装,Java环境可以一起安装. 1.GUI图形界面应用程序 ...
- zend studio 修改字体大小
第一步:进入设置窗口 windows -> preferences第二步:进入修改字体的选项卡. General -> Appearance -> Colors and ...
- linux 各项分布(个人记录)
1.根目录文件 root:存放root用户的相关文件home:存放普通用户的相关文件bin :存放常用命令的目录sbin:要具有一定权限才可以使用的命令mnt :挂在光驱和软盘的目录boot:存放引导 ...
- Java方法、构造方法的重载;创建对象;调用方法
方法的重载 概念:多个同名但是不同参数的方法称为方法的重载 作用:编译器会根据调用时传递的实际参数自动判断具体调用的是哪个重载方法 特点:方法名相同:同一作用域:参数不同:数量不同 类型不同 顺序不同 ...