C++序列式容器vector

一、什么是序列式容器

所谓序列容器,即以线性排列(类似普通数组的存储方式)来存储某一指定类型(例如 int、double 等)的数据,需要特殊说明的是,该类容器并不会自动对存储的元素按照值的大小进行排序。

需要注意的是,序列容器只是一类容器的统称,并不指具体的某个容器,序列容器大致包含以下几类容器:

array<T,N>,vector<T>,deque<T>,list<T>,forward_list<T>

二、vector原理

结构

源码

/*
vector与array数组比较类似 但是array是静态空间,一旦配置了空间就不能够再改变
vecotr是动态空间,随着元素的加入,它的内部机制就会自行扩充空间来容纳新的元素
//下面将真是vector函数的具体实现
//vector是一个连续的线性空间
*/
//alloc是SGI的空间配置器
template <class T,Alloc=alloc>
class vector{
public:
	//vector的嵌套型别定义
	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:
	//以下,simple_alloc是SGI STL的空间配置器专,属配置器 每次配置一个元素大小
	typedef simple_alloc<value_type,Alloc>data_allocator;
	iterator 		start;//表示目前使用空间的头
	iterator 		finish;//表示目前使用空间的尾
	iterator 		end_of_storage;//表示目前可用空间的尾
	void insert_aux(iterator position,const T&x);
	void deallocate(){
	if(start)//如果它不是空的
		data_allocator(start,end_of_storage-start);
	}
	void fill_initialize(size_type n,const T& value){
		start=allocate_and_fill(n,value);
		finish=start+n;
		end_of_storage=finish;
	}
public:
	iterator begin(){return start;}
	iterator end(){return end;}
	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);}
	vector():start(0),finish(0),end_of_storage(0){}
	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(){
		destory(start,finish);//全局函数,见allocate小节
		deallocate();//这是vector的一个member function
	}
	reference front(){return *begin();}//第一个元素
	reference back(){return *(end()-1);}//最后一个元素
	void push_back(const T&x){//将元素插至最尾端
	    if(finish!=end_of_storage){
		construct(finish,x);//全局函数
		++finish;
	    }else
	        insert_aux(end(),x);//vevtor的成员函数

	    }
	void pop_back(){//将最尾端的元素取出来
	    --finish;
	    destroy(finish);//全局函数
	}
	iterator erase(iterator position){//清除某个位置上的元素
	if(position+1!=end())
	copy(position+1,finish,position);//后续元素向前移动
	--finish;
	destory(finish);//全局函数
	return position;
	}
	void resize(size_type new_size,const T & x){
	if(new_size<size()){
		erase(begin()+new_size(),end());
	}else{
		insert(end(),new_size-size(),x);
	}
	void resize(size_type new_size){resize(new_size,T());}
	void clear(){erase(begin(),end());}
protected:
	//配置空间并填满内容
	iterator allocate_and_fill(size_type n,const T&x){
		iterator result=data_allocator::allocate(n);
			uninitialized_fill_n(result,n,x);//全局函数
			return result;
			
        }
    }
};

由源码,可以清晰的看到earse,resize,clear,push_back等函数的结构

三、vector申请内存

注意,所谓的动态增加大小,并不是在原空间之后接续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因对 vector的任何操作,一旦引起空间重新配置,指向原 vector的所有迭代器就都失效了。这是程序员易犯的一个错误,务需小心。

下面我们来看一下是如何vector重新申请内存的

1.如果当前可使用的容量小于要插入的数量,那么就需要重新申请内存

2.如果最大容量减去当前容量小于1,那么抛出vector过长异常

3.申请内存之前,容量需要按照增长50%或为插入的数量

4.申请新内存,将原始空间析构函数释放,重新计算头尾指针的偏移量

实例

vector <int> wgw;
	cout << "initilize size is: " << wgw.size() << endl;
	cout << "initilize capacity is :" << wgw.capacity() << endl;
	wgw.resize(10,2);
	cout << "wgw size is: " << wgw.size() << endl;
	cout << "wgw capacity is :" << wgw.capacity() << endl;

	wgw.resize(3,10);
	cout << "wgw size is :" << wgw.size() << endl;
	cout << "wgw1capacity is:" << wgw.capacity() << endl;
	for (auto &row : wgw) {
		
		std::cout <<row <<std::endl;
	}

参考:

http://c.biancheng.net/view/409.html

https://blog.csdn.net/u012658346/article/details/50725933?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.compare

https://blog.csdn.net/Zyong139064359/article/details/91391865

https://www.jianshu.com/p/e0b59a4a8b51

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值